works for other quizzes and exams too a few slides are updated over the slides in the notes 1 hints...
TRANSCRIPT
Works for other quizzes and exams too
A FEW SLIDES AREUPDATED
OVER THE SLIDES IN THE NOTES1
Hints for Post-Lab Quiz 1
Three types of questions
2
Basic Knowledge Questions
Translation QuestionsYou are given the C++ and must convert into
Blackfin assembly code
Design questionsWork out what is neededGenerate the design – in C++ or in pseudo
codeMost often – convert design code into
Blackfin assembly code
Knowledge type question example
3
A) 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.
CORRECTOR WRONGANSWERNO PARTIAL MARKS
Sometimes more than one correct answer
The Rosetta Stone “Question”You understand columns 1 and 2
4
C++ codeC++ code
NEW C++ keywordNEW C++ keyword
extern “C” long int extern “C” long int Return1( ); Return1( );
long int Return1( ){long int Return1( ){ return 1; return 1;
}}
Blackfin codeBlackfin code
.section program;.section program; .global _Return1; .global _Return1;
_Return1:_Return1: LINK 16; LINK 16;
R0 = 1;R0 = 1;
UNLINK;UNLINK; RTS; RTS;
68K code68K code
.section code;.section code; .global _Return1; .global _Return1;
_Return1:_Return1: LINK #-16, A4; LINK #-16, A4;
MOVE.L #1, D0;MOVE.L #1, D0;
UNLINK A4;UNLINK A4; RTS; RTS;
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?
First design the code in pseudo “C”
#include <blackfin.h>
bool ChipVersion(version) {
chipID = *pCHIPID & 0xF;
if (chipID == version)
return true;
else
return false;
}
Same sort of code as ReadTemperature in Assign 1
6
Now forget the question and just translate the code “line by line”
7
#include <blackfin.h>
bool ChipVersion(version) {
chipID = *pCHIPID & 0xF;
if (chipID == version)
return true;
else
return false;
}
#include <blackfin.h>#define TRUE 1#define FALSE 0
.section program. .global _ChipVersion;// VERSION IS PARAMETER IN R0_ChipVersion:
P0.L = lo(CHIP_ID); P0.H(…) chipID _R2 = [ID_ADDRESS_P0]; mask_R1 = 0xF; chipID _R2 = chipID _R2 & mask_R1;
temp_return_R1 = TRUE; NOT R0
COMP(chipID _R2, inpar_R0);
IF CC JUMP DONE temp_return_R1 = FALSE;
DONE: return_R0 = temp_return_R1;
….END: RTS
Code was
return value = TRUE
If (chipID = version) then returnValue = false
Return returnValue;
C++ to assembly Example
8
ACCURACYIMPORTANT
TRY TO MATCH ASSEMBLY CODE TO C++ ON A BOX BY BOX BASIS
THEN EASIER TO GIVEPARTIAL MARKS
#define count_R1 R1
count_R1 = 0;
Design Question
9
Next to impossible to mark if not well documentedTherefore 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
10
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.
11
Always check for possible return address and stack errorsLINK -- at the start of a functionUNLINK -- at the end of a function
Always check for NAME_MANGLINGunless using ‘extern “C” ‘ 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
We are using extern “C” to this point in the class. We will get to “function overloading” and “name_mangling” at a latter date
I give marks for you coding in a waythat saves time in Labs.
Because the same techniquesaves me time when marking
Avoid pointer errors that would take a lot of time to fix in the laboratory
12
If the memory location is shown as extern in C++ or .extern in Assembly
extern long int funVariable;
.extern _funVariable;
.section program // will accept .section 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
13
If the memory location is shown without the word EXTERN long int funVariable = 0;
.section L1_data1; // will accept data, data1 .global _funVariable; .var _funVariable = 0; // Follow the C++ code
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
14
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 <blackfin.h>
.section program; // Will NOT accept missing sections
P0.L = lo(TCOUNT); // will accept HI( ) and LO ( )P0.H = hi(TCOUNT);countInRegisterR0 = [P0];
Understanding what the hi( ) and lo( ) macros do helps in understanding when to use them
15
.section program P0.L = lo(TCOUNT);
P0.H = hi(TCOUNT);
MEANS
P0.L = TCOUNT & 0xFFFF; P0.H = (TCOUNT & 0xFFFF0000) >>16
HINT – #define value CONSTANTSdon’t use magic numbers (CONSTANTS with no meaning)
Easier to mark -- MEANS more marks
16
#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 – Hi, Lo will work for small constants too – and saves anxiety (Do I need to do hi / low or not?)
17
#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 cause problemsCode that would waste time in lab, loses marks in Quizzes
18
99999 times out of 100000 the following is wrong
CC = R0 < number; e.g. CC = R0 < 25;
So play the odds – Use the Blackfin (MIPS) RISC register and register operation
R1 = number; CC = R0 < R1;
Will accept CC = (R0 < R1); under exam conditions – extra brackets WILL NOT ACCEPT CC = R1 > R0;
CC conditions are always checked VERY closely in exams as they cause so much problem in the laboratory and in “real life”
LOAD AND STORE OPERATIONS
19
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; no memory constant
NEVER add to memory, [P1] = [P0] +1; add to register R0 = R0 + [P0];
Register operationsAdd a small number
20
Make sure that you get the common instructions correct – there are not many to remember
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
21
Make sure that you get the common instructions correct – there are not many instructions that you need to be concerned with
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
22
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 after the jump address has been put into P0 (e.g. P0 = [FP + 4])
Other instructions we have used
23
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;
extern “C” _FeePassVoidFunction – used in this classCALL _FeePassVoidFunction
Other instructions we have used
24
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 because it means that you known that this name is NM (name mangled) and could look up the answer if the exam was open book
CALL _FeePassIntFunction__Fi (little I)
// void FeePassIntFunction(long int);
CALL _FeePassIntFunction__NM2 -- okay in exam
Other instructions we have used
25
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 );
When to use a register andwhen to use memory
26
.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 = hi(_value); P0.L = lo(_value); // value = value + 6; R1 = [P0]; R1 += 6;
[P0] = R1;
P1.H = hi(_fum_value); P1.L = lo(_fum_value); // fum_value = fum_value + 6; R2 = [P1]; R2 += 6;
[P1] = R2; ……… // Rest of the function
Variable “outside” a function
MUST BE STORED IN MEMORY.setion L1_DATA
Very often the answer must be got from memory. Some math done and then put back into memory
When to use a register andwhen to use memory
27
.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
Variable passed into a function
Is already in a register
R0 in this case