f28pl1 programming languages lecture 4: assembly language 3
TRANSCRIPT
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) = Rdi.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+4i.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 0x20000200
0x200001FC
0x200001F8
0x20000200
0x22
0x11
Example: swap R1 & R2R1
R2
R13 0x20000200
0x200001FC
0x200001F8
0x200001FC
0x22
0x11
PUSH {R1}PUSH {R2}
0x11
PUSH {R1}PUSH {R2}POP {R1}POP {R2}
Example: swap R1 & R2R1
R2
R13 0x20000200
0x200001FC
0x200001F8
0x200001F8
0x22
0x11
0x11
0x22
PUSH {R1}PUSH {R2}POP {R1}POP {R2}
Example: swap R1 & R2R1
R2
R13 0x20000200
0x200001FC
0x200001F8
0x200001FC
0x22
0x22
0x11
0x22
PUSH {R1}PUSH {R2}POP {R1}POP {R2}
Example: swap R1 & R2R1
R2
R13 0x20000200
0x200001FC
0x200001F8
0x20000200
0x11
0x22
0x11
0x22
PUSH {R1}PUSH {R2}POP {R1}POP {R2}
Evaluation order
• may wish to rearrange order of evaluation• to optimise register use/number of instructionsexp1 + exp2 exp2 + exp1
e.g. A+B*C B*C+Aexp1 * exp2 exp2 * exp1
e.g. A*(B+C) (B+C)*Aexp1 * 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 variablesint inc(int * x){ *x = *x+1; return *x; }int a;a = 2;a+inc(&a) 2+3 5inc(&a)+a 3+3 6
Example: (a-b)/((c-d)/((e-f)/(g-h)))AREA BIGDIV,
CODE; Main__main PROC
EXPORT __main
A RN 1B RN 2C RN 3D RN 4E RN 5F RN 6G RN 7
H RN 8
MOV A,#128
MOV B,#64MOV C,#32MOV D,#16MOV E,#8MOV F,#4MOV G,#2MOV 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-BSUB 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 ENDLENDPEND
Areas of memory
AREA name• defines section of memory• may be manipulated as a unit by compilerAREA name,attribute1,...,attributeN
• attributeCODE == machine instructionsDATA == data
Areas of memory
READONLY == not writeable• may be in ROM• default for CODEREADWRITE == writeable• default for DATA
Allocating memory
MAP expr• 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 expr bytes 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
LDR Rd,=label • load Rd with address corresponding to label
Memory access
[Rd] == indirection• use contents of Rd as addressLDR Rt,[Rn] Rt = *Rn• i.e. load Rt from memory whose address is in RnSTR Rt,[Rn] *Rn = Rt • i.e. store Rt at memory whose address is in Rn
Example: swap a & bint 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 4Y FIELD 4T FIELD 4 0x20000008
0x20000004
0x20000000
T
Y
X
Example: swap a & bint 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,=XLDR R2,=YLDR R3,=T
MOV R4,#22STR R4,[R1]MOV R4,#33STR R4,[R2]
R1
R2
R30x20000008
0x20000004
0x20000000
R4
0x20000008
0x20000004
0x20000000
T
Y
X
Example: swap a & bint 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,=XLDR R2,=YLDR R3,=T
MOV R4,#22STR R4,[R1]MOV R4,#33STR R4,[R2]
R1
R2
R30x20000008
0x20000004
0x20000000
R4
0x20000008
0x20000004
0x20000000
T
Y
X
22
22
Example: swap a & bint 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,=XLDR R2,=YLDR R3,=T
MOV R4,#22STR R4,[R1]MOV R4,#33STR R4,[R2]
R1
R2
R30x20000008
0x20000004
0x20000000
R4
0x20000008
0x20000004
0x20000000
T
Y
X
33
22
33
Example: swap a & bint 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 ENDLENDP
END
R1
R2
R30x20000008
0x20000004
0x20000000
R4
0x20000008
0x20000004
0x20000000
T
Y
X
22
22
33
22
Example: swap a & bint 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 ENDLENDP
END
R1
R2
R30x20000008
0x20000004
0x20000000
R4
0x20000008
0x20000004
0x20000000
T
Y
X
22
22
33
22
Example: swap a & bint 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 ENDLENDP
END
R1
R2
R30x20000008
0x20000004
0x20000000
R4
0x20000008
0x20000004
0x20000000
T
Y
X
33
22
33
22
Example: swap a & bint 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 ENDLENDP
END
R1
R2
R30x20000008
0x20000004
0x20000000
R4
0x20000008
0x20000004
0x20000000
T
Y
X
33
33
33
22
Example: swap a & bint 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 ENDLENDP
END
R1
R2
R30x20000008
0x20000004
0x20000000
R4
0x20000008
0x20000004
0x20000000
T
Y
X
22
33
33
22
Example: swap a & bint 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 ENDLENDP
END
R1
R2
R30x20000008
0x20000004
0x20000000
R4
0x20000008
0x20000004
0x20000000
T
Y
X
22
33
22
22
Array space
• array is continuous sequence of bytes
type name[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 25int a[MAX];int i;i = 0;while(i<MAX){ a[i] = i; i = i+1;}
AREA SETA, DATA, READWRITE
SRAM EQU 0x20000000MAP SRAM
MAX EQU 25A FIELD MAX*4 • A is 0x20000000 to 0x20000064
AREA SETA, CODE__main PROC
EXPORT __main
Example: a[i] = i#define MAX 25int A[MAX];int i;i = 0;while(i<MAX){ A[i] = i; i = i+1;}
LDR R1,=A - R1 == A@0x20000000MOV R2,#0 - R2 == i
TEST CMP R2,#MAXBEQ ENDLSTR R2,[R1] - (*A) = iADD R2,#1 - i = i+1ADD R1,#0x04 - A = A+4B TEST
ENDL B ENDLENDPEND
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD
R1,#0x04B TEST
ENDL B ENDLENDPEND
R1
R20
0x20000000
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD R1,#4B TEST
ENDL B ENDLENDPEND
R1
R20
0x20000000
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
0
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD R1,#4B TEST
ENDL B ENDLENDPEND
R1
R21
0x20000000
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
0
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD R1,#4B TEST
ENDL B ENDLENDPEND
R1
R21
0x20000004
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
0
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD R1,#4B TEST
ENDL B ENDLENDPEND
R1
R21
0x20000004
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
1
0
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD R1,#4B TEST
ENDL B ENDLENDPEND
R1
R22
0x20000004
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
1
0
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD R1,#4B TEST
ENDL B ENDLENDPEND
R1
R22
0x20000008
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
1
0
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD R1,#4B TEST
ENDL B ENDLENDPEND
R1
R22
0x20000008
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
1
0
2
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD R1,#4B TEST
ENDL B ENDLENDPEND
R1
R23
0x20000008
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
1
0
2
Example: a[i] = iLDR R1,=AMOV R2,#0
TEST CMP R2,#MAX
BEQ ENDLSTR R2,
[R1]ADD R2,#1ADD R1,#4B TEST
ENDL B ENDLENDPEND
R1
R23
0x2000000C
0x20000008
0x20000004
0x20000000 a[0]
a[1]
a[2]
1
0
2