270 likes | 278 Views
Hints for Post-Lab Quiz 1. Works for other quizzes and exams too. Three types of questions. Basic Knowledge Questions Translation Questions You are given the C++ and must convert into Blackfin assembly code Design questions Work out what is needed
E N D
Hints for Post-Lab Quiz 1 Works for other quizzes and exams too
Three types of questions • Basic Knowledge Questions • Translation Questions • You are given the C++ and must convert into Blackfin assembly code • Design questions • Work out what is needed • Generate the design – in C++ or in pseudo code • Most often – convert design code into Blackfin assembly code
Knowledge type question example CORRECTOR WRONGANSWERNO PARTIAL MARKS Sometimes more than one correct answer • Circle and label with an A -- the icon (menu item) that causes VisualDSP to compile the C++ code, but not build or rebuild the full project. • B) Circle and label with a B -- a Blackfin instruction where a non-volatile register is recovered from the stack.
The Rosetta Stone “Question”You understand columns 1 and 2 Demonstrates ability to transfer knowledgeWhich register is used as the 68K return register?In this code, which register is used as the 68K frame pointer?
C++ to assembly Example ACCURACYIMPORTANT #define count_R1 R1count_R1 = 0; TRY TO MATCH ASSEMBLY CODE TO C++ ON A BOX BY BOX BASIS THEN EASIER TO GIVEPARTIAL MARKS
Design Question • Next to impossible to mark if not well documented • Therefore many marks are given for the C++ or pseudo-code comments • More chance of partial marks if the register names are self documenting
Register documentation example ID_R1.L = lo(CHIPID); // Marker know thatID_R1.H = hi(CHIPID); // R1 used to store ID CC = ID_R1 == version_INPAR_R0; // Marker knows that // R0 used for version// Marker also know that you know first parameter is passed in R0 // and not on the stack – later if you make a mistake version_R1then still a good chance for partial (or full) mark
Avoid errors that would take a lot of time to fix in the laboratory • Always check for possible return address and stack errors • LINK -- at the start of a function • UNLINK -- at the end of a function • Always check for NAME_MANGLING • Variable _fooarray; • Function _FeeFunction__Fv (void) _FeeFunction__Fl (long int) _FeeFunction__NM (not sure) _FeeFunction__NM2 (different not sure) WITH NAME MANGLING – under exam conditions, more interested in that you understand the concept than whether you are getting it exactly correct
Avoid pointer errors that would take a lot of time to fix in the laboratory • If the memory location is shown as extern in C++ or .extern in Assembly extern long int funVariable; .extern _funVariable; .section program // will accept code P0.L = lo(_funVariable);P0.H = hi(_funVariable); _funInRegisterR0 = [P0];
Avoid pointer errors that would take a lot of time to fix in the laboratory • If the memory location is shown without the word EXTERN long int funVariable = 0; .section L1_data1; // will accept data, data .global _funVariable; .var _funVariable = 0; // Follow the C++ funVariable is IN MEMORY and not yet in a register You must move the value from memory into a register .section program P0.L = lo(_funVariable); IS P0.L = _funVariable P0.H = hi( _funVariable); OKAY?funInRegisterR0 = [P0];
Avoid pointer errors that would take a lot of time to fix in the laboratory • If the memory location is known to be part of the special MEMORY LOCATIONS (MMR) used to control special operations of the Blackfin “peripherals” #include <defBF533.h> // will accept <defs.h> #include <macros.h> // will accept <macro.h> .section program P0.L = lo(TCOUNT); // will accept HI( ) and LO ( )P0.H = hi(TCOUNT);countInRegisterR0 = [P0];
Know what the hi( ) and lo( ) macros do .section program P0.L = lo(TCOUNT); P0.H = hi(TCOUNT); MEANS P0.L = TCOUNT & 0xFFFF; P0.H = (TCOUNT & 0xFFFF0000) >>16
HINT – #define CONSTANTSdon’t use CONSTANTS #define MAXVALUE 44000 Either hex or decimal is okay .section program R0.L = lo(MAXVALUE);R0.H = hi(MAXVALUE); HINT: If the person is following “standard” coding conventions then CAPITIALS MEAN CONSTANT – use hi( ), lo( )
HINT – Will work for small constants too #define MAXVALUE 22000 Either hex or decimal is okay .section program R0.L = lo(MAXVALUE);R0.H = hi(MAXVALUE); BUT IN THIS CASE – since the constant is small (short int size) R0 = MAXVALUE; Or R0 = 6; HINT: If it looks like IT MIGHT BE a big constant, then let the assembler worry about it -- use hi( ) and lo( )
Condition codes • 99999 times out of 100000 the following is wrong CC = R0 < number; So play the odds R1 = number; CC = R0 < R1; Will accept CC = (R0 < R1); under exam conditions WILL NOT ACCEPT CC = R1 > R0; CC conditions are always checked VERY closely as they cause so much problem in the laboratory and in “real life”
LOAD AND STORE OPERATIONS • Rule to remember – if the operation would not work on the MIPS, then it will not work on the Blackfin or any other RISC processor register memory R0 = [P1];memory register [P1] = R0; NEVER add to memory, [P1] = [P0] +1; add to register R0 = R0 + [P0];
Register operationsAdd a small number Make sure that you get the common instructions correct – there are not many R0 += pretty_small_number R0 += 6 or R0 += -10;NOT R0 = R0 + 6; • Pretty_small_numbers are just that – pretty small numbers -64 <= num <= +63
Register operationsAdd a larger number • Make sure that you get the common instructions correct – there are not many R1 = larger_number; R0 = R0 + R1; R1 = 0x2000; R0 = R0 + R1; NOT R0 += R1;R1 = 20000; R0 = R0 + R1; R1.L = lo(40000); R1.H = hi(40000); R0 = R0 + R1; HINT: Hexadecimal numbers are easy to work out if they are small (need 16-bits) or very large (need 32-bits). Decimal numbers are not – PLAY THE ODDS – if it looks large in decimal – then use lo( ), hi( ) approach
Other instructions we have used • Make sure that you get the common instructions correct – there are not many common instructions to worry about • JUMP LABEL_END; // OFTEN JUMP (P0); // typically end of function
Other instructions we have used • Make sure that you get the common instructions correct – there are not many • CALL _FeePassVoidFunction__Fv // void FeePassVoidFunction(void); NOTE: CALL _FeePassVoidFunction__Fv // long int FeePassVoidFunction(void); // Returns a value in R0;
Other instructions we have used • Make sure that you get the common instructions correct – there are not many // void FeePassLongIntFunction(long int); • CALL _FeePassLongIntFunction__Fl (little L) CALL _FeePassLongIntFunction__NM -- okay in exam • CALL _FeePassIntFunction__Fi (little I) // void FeePassIntFunction(long int); CALL _FeePassIntFunction__NM2 -- okay in exam
Other instructions we have used • Make sure that you get the common instructions correct – there are not many • R0 = 7; CALL _FeeFunction__Fl; // FeeFunction( 7); • R1 = 6; R0 = 7; CALL _FumFunction__NM; // FumFunction(7, 6 );
Make sure that you get the common instructions correct – there are not many R0 = 7; CALL _FeeFunction__Fl; // FeeFunction( 7); R1 = 6; R0 = 7; CALL _FumFunction__NM; // FumFunction(7, 6 ); Other instructions we have used
When to use a register andwhen to use memory .extern _value; // extern long int value.section L1_data; .global _fum_value; // long int fum_value; .var _fum_value; .section program; .global _FooFunction__Fl; // void FooFunction(long int passed_Fickle) { _FooFunction__Fl: LINK 16; passed_Fickle_R0 += 6; // passed_Fickle = passed_Fickle +6;P0.H = _value; // value = value + 6; P0.L = _value; R1 = [P0]; R1 += 6; [P0] = R1; P1.H = _fum_value; // fum_value = fum_value + 6; P1.L = _fum_value; R2 = [P1]; R2 += 6; [P1] = R2; ……… // Rest of the function
When to use a register andwhen to use memory .section program; .global _FooFunction__Fl; // void FooFunction(long int passed_Fickle) { _FooFunction__Fl: LINK 16; passed_Fickle_R0 += 6; // passed_Fickle = passed_Fickle +6;#define value_R1 R1 // long int value value_R1 += 6; // value = value + 6; #define fum_valueR2 R2 // long int fum_value; fum_value_R2 += 6; // fum_value = fum_value + 6; ……… // Rest of the function