320 likes | 477 Views
F28PL1 Programming Languages. Lecture 3: Assembly Language 2. Running assembly programs on the ARM-MDK. ARM-MDK does not simulate a bare CPU oriented to embedded systems with memory, peripherals etc STM32-Discovery board is: STMicroelectronics - STM32F103VB assumes no operating system
E N D
F28PL1 Programming Languages Lecture 3: Assembly Language 2
Running assembly programs on the ARM-MDK • ARM-MDK does not simulate a bare CPU • oriented to embedded systems with memory, peripherals etc • STM32-Discovery board is: • STMicroelectronics - STM32F103VB • assumes no operating system • must provide start up file • code to initialise peripherals, interrupts etc • STM32-Discovery uses: • STM32F10x.s – .s == assembler
Running assembly programs on the ARM-MDK • start up file associates reset button on board with: ; Reset Handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main LDR R0, =__main BX R0 ENDP • ; text == comment • Reset_Handler– labelled procedure start • PROC – start of procedure • EXPORT Reset_Handler– make Reset_Handler visible externally
Running assembly programs on the ARM-MDK ; Reset Handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main LDR R0, =__main BX R0 ENDP • IMPORT – make external label __main visible internally • LDR R0,=__main – load R0 with address for __main • BX R0 – branch indirect on R0 i.e. set PC to address for __main from R0 • ENDP - end procedure – not a return!
Running assembly programs on the ARM-MDK • ARM-MDK expects every project to include a main.c • usually defining a main function • compiler generates assembly with EXPORTed__main label • start up then IMPORTs __main • can’t embed Thumb2 assembly language in C • provide a dummy main.c containing only: /* main.c */ • GJM’s main.c
Running assembly programs on the ARM-MDK • provide own assembly language file with __main: AREA ASMmain, CODE ; Main __main PROC EXPORT __main <assembly code> ENDL B ENDL ENDP END • AREA – introduces block of code or data – name + attributes • __main – labelled procedure start • EXPORT __main – make __main visible externally
Running assembly programs on the ARM-MDK AREA ASMmain, CODE ; Main __main PROC EXPORT __main <assembly code> ENDL B ENDL ENDP END • ENDL B ENDL – endless loop at end of program • END – end of source file • template in GJM’s ASMmain.s
Create new project • create a new folder for new project • copy dummy main.c to folder • copy ASMmain.s template to folder • run KeilμVision 4 • Project -> New μVision Project • in new folder • give project same name
Create new project • Select Device for Target -> STMicroelectronics -> STM32F103VB • OK • Copy STM32 Startup Code to Project Folder and Add Project to File? • Yes • Project Window now shows: +Target 1 • select + • Project Window now shows: +Target 1+Source Group 1
Create new project • select inner + • Project Window now shows: +Target 1+Source Group 1+STM32F10x.s • Source Group 1 /right mouse button… • …Add Files To Group ‘Source Group 1’ • Add: main.c and (possibly renamed) ASMmain.s • Close • ASMmain.s/double left mouse button • ASMmain.sopens in tabbed window
Compile/assemble • add your assembler code • Project -> Build Target • details in lower window • fix program and repeat until: “project.axf" - 0 Error(s), 0 Warning(s).
Execute program on simulator • Debug -> Start/Stop Debug Session • OK • View -> Register Window • View -> Disassembly Window • select STM32F10x.s tab
Execute program on simulator • select reset button: • yellow arrow points at: LDR R0,=__main • repeatedly select step button: • watch indicated instruction & registers changing • to leave simulator: Debug -> Start/Stop Debug Session RST
Multiply & divide MUL {Rd, }Rn,Rm Rd = Rn*Rm UDIV {Rd,}Rn,Rm Rd = Rn/Rm • unsigned • rounds down i.e. 7/3 == 2
Expressions • for: var1=var2 op var3 • with: var1RN R1 var2 RN R2 var3RN R3 op R1,R2,R3 • e.g. x = y*z; x RN 1 y RN 2 z RN 3 MUL x,y,z
Expressions • for: var1=var2 op1 var3 op2 var4 • if op1 andop2 have same precedence • or op1 has higher precedence than op2 op1 R1,R2,R3 op2 R1,,R4 e.g. x = y*z-a; ... a RN 4 MUL x,y,z SUB x,a
Expressions • for: var1=var2 op1 var3 op2 var4 • if op2 has higher precedence thanop1 • must evaluate op2 expression in new register op2 Ri,R3,R4 op1 R1,,R2,Ri e.g. x = y+z*a; MUL R5,z,a ADD x,y,R5 e.g. x = y*(z+a) ADD R5,z,a MUL x,y,R5
Expressions • draw expression tree • allocate registers to nodes • from bottom left • if expression in assignment then start with register for destination variable • accumulate into register for left operand • can re-use any register whose value is no longer required
Example: Pythagorus int x; /* R1 */ int y; /* R2 */ int z; /* R3 */ int p; /* R4 */ x = 3; y = 4; z = 5; if(x*x+y*y==z*z) p=1; else p=0; == * + z z * * x x y y
Example: Pythagorus int x; /* R1 */ int y; /* R2 */ int z; /* R3 */ int p; /* R4 */ x = 3; y = 4; z = 5; if(x*x+y*y==z*z) p=1; else p=0; == * + z z * R5 * x x y y
Example: Pythagorus int x; /* R1 */ int y; /* R2 */ int z; /* R3 */ int p; /* R4 */ x = 3; y = 4; z = 5; if(x*x+y*y==z*z) p=1; else p=0; == * + z z * R5 * R6 x x y y
Example: Pythagorus int x; /* R1 */ int y; /* R2 */ int z; /* R3 */ int p; /* R4 */ x = 3; y = 4; z = 5; if(x*x+y*y==z*z) p=1; else p=0; == * + R5 z z * R5 * R6 x x y y
Example: Pythagorus int x; /* R1 */ int y; /* R2 */ int z; /* R3 */ int p; /* R4 */ x = 3; y = 4; z = 5; if(x*x+y*y==z*z) p=1; else p=0; == * R6 + R5 z z * R5 * R6 x x y y
Example: Pythagoras int x; /* R1 */ int y; /* R2 */ int z; /* R3 */ int p; /* R4 */ x = 3; y = 4; z = 5; if(x*x+y*y==z*z) p=1; else p=0; == CMP * R6 + R5 z z * R5 * R6 x x y y
Example: Pythagoras int x; int y; int z; int p; x = 3; y = 4; z = 5; if(x*x+y*y==z*z) p=1; else p=0; AREA PYTH, CODE ; Main __main PROC EXPORT __main x RN 1 y RN 2 z RN 3 p RN 4 MOV x,#3 MOV y,#4 MOV z,#5
Example: Pythagoras int x; int y; int z; int p; x = 3; y = 4; z = 5; if(x*x+y*y==z*z) p=1; else p=0; MUL R5,x,x MUL R6,y,y ADD R5,R6 MUL R6,z,z CMP R5,R6 BEQ SAME MOV p,#0 B ENDL SAME MOV p,#1 ENDL B ENDL ENDP END
Structured programming • assembly language requires intricate use of labels & branches • easy to produce “spaghetti code” • design assembly programs using high level program structures • condition • iteration • use template to translate high level to label + branch
Structured programming: if IFexp1 op exp2THEN command1 ELSE command2 not(=) NE not(!=) EQ not(<) GE not(<=) GT not(>) LE not(>=) LT Ri= exp1 Rj = exp2 CMP Ri,Rj Bnot(op) IFALSE command1 B IEND IFALSE command2 IEND
Structured programming: if IFexp1 op exp2THEN command Ri= exp1 Rj = exp2 CMP Ri,Rj Bnot(op) IEND command IEND
Structured programming: while WHILEexp1 op exp2DO command WLOOP Ri= exp1 Rj = exp2 CMP Ri,Rj Bnot(op) WEND command B WLOOP WEND
Example: is x prime? • dreadful algorithm...! int x; int n; int p; x = 23; n = 2; p = 1; while(n<x) if(x%n==0) { p = 0; break; } else n = n+1; AREA PYTH, CODE ; Main __main PROC EXPORT __main x RN 1 n RN 2 p RN 3 MOV x,#25 MOV n,#2 MOV p,#1
Example: is x prime? • dreadful algorithm...! int x; int n; int p; x = 23; n = 2; p = 1; while(n<x) if(x%n==0) { p = 0; break; } else n = n+1; TEST CMP n,x BEQ ENDL UDIV R4,x,n MUL R4,n CMP R4,x BNE NOTP MOV p,#0 B ENDL NOTP ADD n,#1 B TEST ENDL B ENDL ENDP END n<x x%n==0 (x/n)*n==x p=0; break n = n+1