Assembly Language Review Being able to repeat on the Blackfin the things we were able to do on the MIPS 01/26/20 Review of 50% OF ENCM369 in 50 minutes 1 Assembly code things to review 50% of ENCM369 in 50 minutes YOU ALREADY KNOW HOW TO DO THESE THINGS ON THE MIPS Being able to ADD and SUBTRACT the contents of two data registers Being able to bitwise AND and bitwise OR the contents of two data registers Being able to place a (small) required value into a data register Being able to place a (large) required value into a data register Being able to write a simple void function (returns nothing) Being able to write a simple int function (returns and int)

Being able to ADD and SUBTRACT the contents of two memory locations IF YOU CAN DO THE SAME THING ON THE BLACKFIN THEN THATS 50% OF THE LABS AND 50% OF EXAMS ACED 01/26/20 2 / 28 Being able to ADD and SUBTRACT the contents of two data registers It makes sense to ADD and SUBTRACT values stored in data registers Blackfin DATA registers R0, R1, R2 and R3 R0 = R1 + R2; // Addition e.g. 4 + 6 10 (Decimal) 0x14 + 0x16 0x2A (Hexadecimal) R3 = R1 R2; // Subtraction e.g. 4 - 6 8 (Decimal) 0x14 - 0x16 0xFFFFFFFE (Hexadecimal) 01/26/20 Review of 50% OF ENCM369 in 50 minutes

3 / 28 Being able to bitwise AND and OR the contents of two data registers It makes sense to perform OR and AND operations on bit- patterns stored in data registers. NEVER perform ADD and SUBTRACT operations on bitpatterns stored in data registers. (Although SOMETIMES get the correct answer code defect) Blackfin DATA registers R0, R1, R2 and R3 R0 = R1 & R2; // Bitwise AND e.g. B11001100 & B01010101 B01000100 R3 = R1 | R2; // Bitwise OR e.g. B11001100 | B01010101 B11011101 01/26/20 Review of 50% OF ENCM369 in 50 minutes 4 / 28

Is it a bit pattern or a value? Hints from C++ If the code developer is consistent when writing the code then Bit patterns are normally stored as unsigned integers e.g. unsigned int bitPattern = 0xFFA2345FF Values are normally stored as signed integers e.g. signed int fooValue = -1; or int fooValue = -1; where the word signed is understood. Understood means its there but not actually written down (which means that it sometimes causes defects in your code) Note that bitPattern = 0xFFFFFFFF and fooValue = -1 are STORED as the SAME bit pattern 0xFFFFFFFFF in the registers and memory of MIPS and Blackfin processor 01/26/20 Review of 50% OF ENCM369 in 50 minutes 5 / 28 Being able to place a required

value into a data register 1 Like the MIPS, the Blackfin uses 32 bit instructions all registers are the same size to ensure maximum speed of the processor (highly pipelined instructions). The 32 bit Blackfin instruction for placing a value into a data register has two parts to have16 bits available for describing the instruction and 16 bits for describing the signed 16 bit value to be put into a signed 32 bit data register. This means that you have to use 2 32-bit instructions to put large values into a data register (SAME AS MIPS). 01/26/20 Review of 50% OF ENCM369 in 50 minutes 6 / 28

Placing a value into a data register Similar to MIPS, different syntax R1 = 0; legal -- 0 = 0x0000 (signed 16 bits); (becomes the signed 32 bit 0x00000000 after auto sign extension of the 16-bit value 0x0000) R0 = 33; legal -- 33 = 0x0021 (signed 16 bits) (becomes the signed 32 bit 0x00000021 after auto sign extension of the 16-bit value 0x0021) R2 = -1; legal -- -1 = 0xFFFF (signed 16 bits) (becomes the signed 32 bit 0xFFFFFFFF after auto sign extension of the 16-bit value 0xFFFF)

R3 = -33; legal -- -33 = 0xFFDE (signed16 bits) (becomes the signed 32 bit 0xFFFFFFDE after auto sign extension of the 16-bit value 0xFFDE) 01/26/20 Review of 50% OF ENCM369 in 50 minutes 7 / 28 Placing a large value into a data register This approach does not work for any large value R1 = 40000; DOES NOT WORK WITH MIPS EITHER illegal -- as 40000 cant be expressed as a signed 16-bit value it is the positive 32 bit value 0x00009C40

If the assembler tried to take the bottom 16 bits of the decimal 40000 and sign extend it then this would happen 16-bit hex value 9C40 (1001 1100 0100 0000) becomes 32-bit hex value after sign extension 0xFFFF9C40 which is a negative value Therefore it is illegal to try to put a 32-bit value directly into a register; just as it would be illegal to try in MIPS. 01/26/20 Review of 50% OF ENCM369 in 50 minutes 8 / 28 Placing a large value into a data register If the assembler tried to take the bottom 16 bits of the decimal 40000 and sign extend it then this would happen 16-bit hex value 9C40 (1001 1100 0100 0000) becomes 32-bit hex value after sign extension 0xFFFF9C40 which is a negative value illegal just as it would be in MIPS // Want to do R1 = 40000

// Instead must do operation in two steps as with MIPS #include R1.L = lo(40000); // Tell assembler to put bottom // 16-bits into low part of R1 register R1.H = hi(40000); // Tell assembler to put top // 16-bits into high part of R1 register 01/26/20 9 / 28 Placing a large value into a data register A common error in the laboratory and exams is getting this two step thing wrong . Forgetting the second step is easy to do just as easy to forget on Blackfin as on MIPS // Want to do R1 = 41235 R1.L = lo(41235); // bottom 16-bits into low part of R1 register R1.H = hi(41325); // top 16-bits into high part of R1 register FORGOTTEN SECOND STEP RECOMMENDED SYNTAX TO AVOID CODE DEFECTS

#define LARGEVALUE 41235 // C++ - like syntax R1.L = lo(LARGEVALUE); R1.H = hi(LARGEVALUE); Yes you CAN put multiple Blackfin assembly language instructions on one line 01/26/20 Review of 50% OF ENCM369 in 50 minutes 10 / 28 A void function returns NO VALUE extern C void SimpleVoidASM(void) #include Things in red were cut-and-pasted using the editor to save Lab. time .section program;

.global _SimpleVoidASM; _SimpleVoidASM: _SimpleVoidASM.END: RTS; 01/26/20 Review of 50% OF ENCM369 in 50 minutes 11 / 28 A simple int function return a value extern C int SimpleIntASM(void) #include Things in red were cut-and-pasted using the editor .section program; .global _SimpleIntASM; _SimpleIntASM: R0 = 7; // Return 7 _SimpleIntASM.END: RTS;

01/26/20 Review of 50% OF ENCM369 in 50 minutes 12 / 28 Being able to ADD and SUBTRACT the contents of two memory locations Lets set up a practical situation A background thread is putting values into an array. Processor could be MIPS or Blackfin For background thread read interrupt service routine or ISR. ISR work in parallel with the foreground thread that is doing the major work on the microprocessor Write a subroutine (returns int) that adds together the first two values of this shared array 01/26/20

Review of 50% OF ENCM369 in 50 minutes 13 / 28 Start with a copy of the int function extern C int SimpleIntASM(void) #include Things in red were cut-and-pasted using the editor .section program; .global _SimpleIntASM; _SimpleIntASM: R0 = 7; // Return 7 _SimpleIntASM.END: RTS; 01/26/20 Review of 50% OF ENCM369 in 50 minutes 14 / 28

Modify to be extern C int AddArrayValuesASM(void) #include Things in red were cut-and-pasted using the editor .section program; .global _AddArrayValuesASM; _AddArrayValuesASM: R0 = 7; // Return 7 _AddArrayValuesASM.END: RTS; 01/26/20 Review of 50% OF ENCM369 in 50 minutes 15 / 28 Add a data array #include .section L1_data; .byte4 _fooArray[2];

Things in red were cut-and-pasted using the editor // Syntax for building an array // of 32-bit values .section program; .global _AddArrayValuesASM; _AddArrayValuesASM : R0 = 7; // Return 7 _AddArrayValuesASM .END: RTS; 01/26/20 Review of 50% OF ENCM369 in 50 minutes 16 / 28 Plan to return sum, initialize sum to 0 #include .section L1_data;

.byte4 _fooArray[2]; Things in red were cut-and-pasted using the editor .section program; .global _AddArrayValuesASM; _AddArrayValuesASM: #define sum_R0 R0 sum_R0 = 0; // register int sum; // sum = 0; _AddArrayValuesASM .END: RTS; 01/26/20 Review of 50% OF ENCM369 in 50 minutes 17 / 28

Place the memory address of the start of the array into a pointer register . Other code Things in red were cut-and-pasted using the editor .section L1_data; .byte4 _fooArray[2]; .section program; .global _AddArrayValuesASM; _AddArrayValuesASM : #define sum_R0 R0 // register int sum; sum_R0 = 0; // sum = 0; #define pointer_to_array_P1 P1 P1.L = lo(_fooArray); P1 is a POINTER register

(address register) // register int * pointer_to_array P1.H = hi(_fooArray); // pointer_to_array = &fooArray[0]; _AddArrayValuesASM .END: RTS; 01/26/20 Review of 50% OF ENCM369 in 50 minutes 18 / 28 Read the contents of the first array location into register R1 and add to sum_R0; . Other code Things in red were cut-and-pasted using the editor .section L1_data;

.byte4 _fooArray[2]; .section program; .global _AddArrayValuesASM; _AddArrayValuesASM : #define sum_R0 R0 // register int sum; sum_R0 = 0; // sum = 0; #define pointer_to_array_P1 P1 P1L = lo(_fooArray); // register int * pointer_to_array P1.H = hi(_fooArray); // pointer_to_array = &fooArray[0]; R1 = [pointer_to_array_P1]; sum_R0 = sum_R0 + R1; // int temp = fooArray[0]; // sum = sum + temp _AddArrayValuesASM.END: RTS;

01/26/20 Review of 50% OF ENCM369 in 50 minutes 19 / 28 Read the contents of the second array location into register R1 and add to sum_R0; . Other code Things in red were cut-and-pasted using the editor .section L1_data; .byte4 _fooArray[2]; .section program; .global _AddArrayValuesASM; _AddArrayValuesASM: #define sum_R0 R0 // register int sum; sum_R0 = 0; // sum = 0;

#define pointer_to_array_P1 P1 // register int * pointer_to_array P1.L = lo(_fooArray); P1.H = hi(_fooArray); // pointer_to_array = &fooArray[0]; R1 = [pointer_to_array_P1]; // int temp = fooArray[0]; sum_R0 = sum_R0 + R1; // sum = sum + temp R1 = [pointer_to_array_P1 + 4]; sum_R0 = sum_R0 + R1; // temp = fooArray[1]; // sum = sum + temp _AddArrayValuesASM .END: RTS; 01/26/20 20 / 28 Add code to .ASM (assembly) file

01/26/20 Review of 50% OF ENCM369 in 50 minutes 21 / 28 Assignment 1, Q1 Demo answer 01/26/20 Review of 50% OF ENCM369 in 50 minutes 22 / 28 Assembly code things to review 50% of ENCM369 in 50 minutes YOU ALREADY KNOW HOW TO DO THESE THINGS ON THE MIPS Being able to ADD and SUBTRACT the contents of two data registers Being able to bitwise AND and bitwise OR the contents of two data registers Being able to place a (small) required value into a data register

Being able to place a (large) required value into a data register Being able to write a simple void function (returns nothing) Being able to write a simple int function (returns and int) Being able to ADD and SUBTRACT the contents of two memory locations IF YOU CAN DO THE SAME THING ON THE BLACKFIN THEN THATS 50% OF THE LABS AND 50% OF EXAMS ACED 01/26/20 23 / 28