450 likes | 577 Views
F28PL1 Programming Languages. Lecture 4: Assembly Language 3. Not enough registers?. need to use memory for: larger data structures temporary storage of partial values stack partial results e.g. during arithmetic hold state & parameters during function call
E N D
F28PL1 Programming Languages Lecture 4: Assembly Language 3
Not enough registers? • need to use memory for: • larger data structures • temporary storage of partial values • stack • partial results e.g. during arithmetic • hold state & parameters during function call • must allocate & manage all other memory explicitly
Stack • stack pointer == R13 == SP • descending stack • stack pointer • decremented on PUSH • incremented on POP • SP starts at 0x20000200 for STM32-Discovery
Stack PUSH {Rd} SP = SP-4 (*SP) = Rd i.e. • decrement SP by 4 bytes == 1 word down • to next free stack location • store Rd at memory address indicated by SP
Stack POP {Rd} Rd = (*SP) SP = SP+4 i.e. • set Rd to contents of address indicated by SP • increment SP by 4 bytes == 1 word up • next free stack location is last used
Example: swap R1 & R2 PUSH {R1} PUSH {R2} POP {R1} POP {R2} R1 R2 R13 0x11 0x22 0x20000200 0x20000200 0x200001FC 0x200001F8
Example: swap R1 & R2 PUSH {R1} PUSH {R2} POP {R1} POP {R2} R1 R2 R13 0x11 0x22 0x200001FC 0x20000200 0x11 0x200001FC 0x200001F8 PUSH {R1} PUSH {R2}
Example: swap R1 & R2 PUSH {R1} PUSH {R2} POP {R1} POP {R2} R1 R2 R13 0x11 0x22 0x200001F8 0x20000200 0x11 0x200001FC 0x22 0x200001F8
Example: swap R1 & R2 PUSH {R1} PUSH {R2} POP {R1} POP {R2} R1 R2 R13 0x22 0x22 0x200001FC 0x20000200 0x11 0x200001FC 0x22 0x200001F8
Example: swap R1 & R2 PUSH {R1} PUSH {R2} POP {R1} POP {R2} R1 R2 R13 0x22 0x11 0x20000200 0x20000200 0x11 0x200001FC 0x22 0x200001F8
Evaluation order • may wish to rearrange order of evaluation • to optimise register use/number of instructions exp1 + exp2 exp2 + exp1 e.g. A+B*C B*C+A exp1 * exp2 exp2 * exp1 e.g. A*(B+C) (B+C)*A exp1 * exp2 + exp1 * exp3 exp1 * (exp2 + exp3) e.g. X*X+X*Y X*(X+Y) (X+Y)*X
Evaluation order • sometimes need to preserve left to right order • e.g. expression contains function calls that change shared variables int inc(int * x) { *x = *x+1; return *x; } int a; a = 2; a+inc(&a) 2+3 5 inc(&a)+a 3+3 6
Example: (a-b)/((c-d)/((e-f)/(g-h))) AREA BIGDIV, CODE ; Main __main PROC EXPORT __main A RN 1 B RN 2 C RN 3 D RN 4 E RN 5 F RN 6 G RN 7 H RN 8 MOV A,#128 MOV B,#64 MOV C,#32 MOV D,#16 MOV E,#8 MOV F,#4 MOV G,#2 MOV H,#1 • strict left to right • suppose only R9 & R10 spare
Example: (a-b)/((c-d)/((e-f)/(g-h))) SUB R9,A,B • R9 == A-B SUB R10,C,D • R10 == C-D • need register for E-F • put A-B on stack PUSH {R9} • *SP == A-B SUB R9,E,F • R9 == E-F • need register for G-H • put C-D on stack PUSH {R10} • *SP == C-D SUB R10,G,H • R10 == G-H UDIV R9,R10 • R9 == (E-F)/(G-H) • R10 free • get C-D from stack POP {R10} • R10 == C-D UDIV R10,R9 • R10 == (C-D)/((E-F)/(G-H))
Example: (a-b)/((c-d)/((e-f)/(g-h))) • R9 free • get A-B from stack POP {R9} • R9 == A-B UDIV R9,R10 • R9 == (A-B)/((C-D)/((E-F)/(G-H))) ENDL B ENDL ENDP END
Areas of memory AREA name • defines section of memory • may be manipulated as a unit by compiler AREA name,attribute1,...,attributeN • attribute CODE == machine instructions DATA == data
Areas of memory READONLY == not writeable • may be in ROM • default for CODE READWRITE == writeable • default for DATA
Allocating memory MAPexpr • set start of a storage map • starting at address expr {VAR} • assembler storage map location counter • starts at expr • e.g. MAP 0x20000000 • {VAR} == 0x20000000 == start of SRAM
Allocating memory {label} FIELD expr • allocate exprbytes from {VAR} • label is associated with initial value of {VAR} • {VAR} = {VAR} + expr • e.g. X FIELD 4 • X is 4 bytes from 0x20000000 • {VAR} is now 0x20000004
Memory access • cannot access memory directly • load register with memory address • access memory indirect on register • load register with absolute address using MOV LDRRd,=label • load Rd with address corresponding to label
Memory access [Rd] == indirection • use contents of Rd as address LDRRt,[Rn] Rt = *Rn • i.e. load Rtfrom memory whose address is in Rn STRRt,[Rn] *Rn= Rt • i.e. store Rtat memory whose address is in Rn
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; AREA SWAP, DATA, READWRITE SRAM EQU 0x20000000 MAP SRAM X FIELD 4 Y FIELD 4 T FIELD 4 0x20000008 T 0x20000004 Y 0x20000000 X
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; AREA SWAP, CODE ; Main __main PROC EXPORT __main LDR R1,=X LDR R2,=Y LDR R3,=T MOV R4,#22 STR R4,[R1] MOV R4,#33 STR R4,[R2] 0x20000000 R1 0x20000004 R2 0x20000008 R3 R4 0x20000008 T 0x20000004 Y 0x20000000 X
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; AREA SWAP, CODE ; Main __main PROC EXPORT __main LDR R1,=X LDR R2,=Y LDR R3,=T MOV R4,#22 STR R4,[R1] MOV R4,#33 STR R4,[R2] 0x20000000 R1 0x20000004 R2 0x20000008 R3 22 R4 0x20000008 T 0x20000004 Y 0x20000000 22 X
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; AREA SWAP, CODE ; Main __main PROC EXPORT __main LDR R1,=X LDR R2,=Y LDR R3,=T MOV R4,#22 STR R4,[R1] MOV R4,#33 STR R4,[R2] 0x20000000 R1 0x20000004 R2 0x20000008 R3 33 R4 0x20000008 T 0x20000004 33 Y 0x20000000 22 X
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; LDR R4,[R1] STR R4,[R3] LDR R4,[R2] STR R4,[R1] LDR R4,[R3] STR R4,[R2] ENDL B ENDL ENDP END 0x20000000 R1 0x20000004 R2 0x20000008 R3 22 R4 0x20000008 22 T 0x20000004 33 Y 0x20000000 22 X
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; LDR R4,[R1] STR R4,[R3] LDR R4,[R2] STR R4,[R1] LDR R4,[R3] STR R4,[R2] ENDL B ENDL ENDP END 0x20000000 R1 0x20000004 R2 0x20000008 R3 22 R4 0x20000008 22 T 0x20000004 33 Y 0x20000000 22 X
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; LDR R4,[R1] STR R4,[R3] LDR R4,[R2] STR R4,[R1] LDR R4,[R3] STR R4,[R2] ENDL B ENDL ENDP END 0x20000000 R1 0x20000004 R2 0x20000008 R3 33 R4 0x20000008 22 T 0x20000004 33 Y 0x20000000 22 X
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; LDR R4,[R1] STR R4,[R3] LDR R4,[R2] STR R4,[R1] LDR R4,[R3] STR R4,[R2] ENDL B ENDL ENDP END 0x20000000 R1 0x20000004 R2 0x20000008 R3 33 R4 0x20000008 22 T 0x20000004 33 Y 0x20000000 33 X
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; LDR R4,[R1] STR R4,[R3] LDR R4,[R2] STR R4,[R1] LDR R4,[R3] STR R4,[R2] ENDL B ENDL ENDP END 0x20000000 R1 0x20000004 R2 0x20000008 R3 22 R4 0x20000008 22 T 0x20000004 33 Y 0x20000000 33 X
Example: swap a & b int x; int y; int t; x = 22; y = 33; t = x; x = y; y = t; LDR R4,[R1] STR R4,[R3] LDR R4,[R2] STR R4,[R1] LDR R4,[R3] STR R4,[R2] ENDL B ENDL ENDP END 0x20000000 R1 0x20000004 R2 0x20000008 R3 22 R4 0x20000008 22 T 0x20000004 22 Y 0x20000000 33 X
Array space • array is continuous sequence of bytes typename[size] • allocate sizeof(type)*size bytes • start register at address of 1st byte • access byte/half word/word indirect on register • add 1/2/4 to register to get to address for next byte/halfword/word
Array access • a[i] == address for a+ i*size(type) • for iterative access to a[i] • 0<= i<size • put address of array in register Ri • on each iteration • access [Ri] • add size(type) to Ri
Example: a[i] = i #define MAX 25 int a[MAX]; inti; i = 0; while(i<MAX) { a[i] = i; i = i+1; } AREA SETA, DATA, READWRITE SRAM EQU 0x20000000 MAP SRAM MAX EQU 25 A FIELD MAX*4 • A is 0x20000000 to 0x20000064 AREA SETA, CODE __main PROC EXPORT __main
Example: a[i] = i #define MAX 25 int A[MAX]; inti; i = 0; while(i<MAX) { A[i] = i; i = i+1; } LDR R1,=A - R1 == A@0x20000000 MOV R2,#0 - R2 == i TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] - (*A) = i ADD R2,#1 - i = i+1 ADD R1,#0x04 - A = A+4 B TEST ENDL B ENDL ENDP END
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#0x04 B TEST ENDL B ENDL ENDP END 0x20000000 R1 0 R2 0x20000008 a[2] 0x20000004 a[1] 0x20000000 a[0]
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#4 B TEST ENDL B ENDL ENDP END 0x20000000 R1 0 R2 0x20000008 a[2] 0x20000004 a[1] 0x20000000 0 a[0]
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#4 B TEST ENDL B ENDL ENDP END 0x20000000 R1 1 R2 0x20000008 a[2] 0x20000004 a[1] 0x20000000 0 a[0]
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#4 B TEST ENDL B ENDL ENDP END 0x20000004 R1 1 R2 0x20000008 a[2] 0x20000004 a[1] 0x20000000 0 a[0]
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#4 B TEST ENDL B ENDL ENDP END 0x20000004 R1 1 R2 0x20000008 a[2] 0x20000004 1 a[1] 0x20000000 0 a[0]
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#4 B TEST ENDL B ENDL ENDP END 0x20000004 R1 2 R2 0x20000008 a[2] 0x20000004 1 a[1] 0x20000000 0 a[0]
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#4 B TEST ENDL B ENDL ENDP END 0x20000008 R1 2 R2 0x20000008 a[2] 0x20000004 1 a[1] 0x20000000 0 a[0]
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#4 B TEST ENDL B ENDL ENDP END 0x20000008 R1 2 R2 0x20000008 2 a[2] 0x20000004 1 a[1] 0x20000000 0 a[0]
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#4 B TEST ENDL B ENDL ENDP END 0x20000008 R1 3 R2 0x20000008 2 a[2] 0x20000004 1 a[1] 0x20000000 0 a[0]
Example: a[i] = i LDR R1,=A MOV R2,#0 TEST CMP R2,#MAX BEQ ENDL STR R2,[R1] ADD R2,#1 ADD R1,#4 B TEST ENDL B ENDL ENDP END 0x2000000C R1 3 R2 0x20000008 2 a[2] 0x20000004 1 a[1] 0x20000000 0 a[0]