Assembly Programming
Assembly Programming
EE 342 Microprocessors
ASSEMBLY PROGRAMMING
MSP430 Assembler
High Level vs. Assembly
Assembly Code
Assembly Process
Code Examples
Operators
Control Structures
Functions
Arrays and Pointers
Disclaimer: Most of the following slides are adopted from Prof. Paul Ropers course notes
with his kind permission.
1
Reading List
Algorithms
Language (Program)
Programmable
Computer Specific
Micro-architecture
Manufacturer Specific
Circuits
Devices
3
Assembler
An assembler
translates a program
into machine code
An assembly program
is a text file
Assembler Syntax
;
;
;
;
Data Space
variable var1 declaration
Program Space
move R4 contents to R5
COUNT
Labels
;
;
WDT_ISR:
Field 4
.equ
Instructions
2000
;-----------------------------------------------------------------------------.data
; data
.bss
cnt,2
; ISR counter
;-----------------------------------------------------------------------------.text
; Program reset
RESET:
mov.w
#0x0280,SP
; Initialize stack pointer
mov.w
#WDT_MDLY_0_5,&WDTCTL
; Set Watchdog interval to ~0.5ms
mov.b
#WDTIE,&IE1
; Enable WDT interrupt
bis.b
#0x01,&P1DIR
; P1.0 output
bis.b
#0x20,&P4DIR
; P4.0 output
mov.w
#COUNT,&cnt
; initialize counter
bis.w
#LPM0+GIE,SR
; Enter LPM0 w/ interrupt
jmp
$
; Loop forever; interrupts do all
WDT_exit:
Directives
Comments
#0x20,&P4OUT
&cnt
WDT_exit
#COUNT,&cnt
#0x01,&P1OUT
; pulse buzzer
; decrement counter
.sect
.word
".int10"
WDT_ISR
.sect
.word
.end
".reset"
RESET
reti
; initialize counter
; toggle P1.0
; return from interrupt
Assembler Directives
Example: Operators
variable = expression
int x = 9;
sub.w #2,sp
mov.w #9,0(sp)
;*******************************************************************************
;
CS/ECEn 124 Example Code
;*******************************************************************************
.cdecls C,LIST, "msp430x22x4.h
; include C header
COUNT
Directives
.equ
Stack
2000
x = x + 4;
;-----------------------------------------------------------------------------.data
; data
.bss
cnt,2
; ISR counter
;-----------------------------------------------------------------------------.text
; Program reset
RESET:
mov.w
#0x0280,SP
; Initialize stack pointer
mov.w
#WDT_MDLY_0_5,&WDTCTL
; Set Watchdog interval to ~0.5ms
bis.w
#LPM0+GIE,SR
; Enter LPM0 w/ interrupt
jmp
$
; Loop forever; interrupts do all
.sect
.word
.end
10
".reset"
RESET
sp
add.w #4,0(sp)
11
0x05fa
0x05fc
0x05fe
0x05f0
...
0x0600
12
Example: Operators
{
int
int
int
x =
y =
x
y
z
x
x
=
=
=
+
+
0x8696:
0x869a:
0x86a0:
0x86a6:
0x86ac:
0x86b0:
0x86b4:
0x86b6:
0x86ba:
10;
20;
30;
4;
y - z;
SP
x
y
z
ret adr
Stack
8031
40B1
40B1
40B1
52A1
411F
512F
811F
4F81
Example: Operators
0006
000A 0000
0014 0002
001E 0004
0000
0002
0004
0002
SUB.W
MOV.W
MOV.W
MOV.W
ADD.W
MOV.W
ADD.W
SUB.W
MOV.W
#0x0006,SP
#0x000a,0x0000(SP)
#0x0014,0x0002(SP)
#0x001e,0x0004(SP)
#4,0x0000(SP)
0x0002(SP),R15
@SP,R15
0x0004(SP),R15
R15,0x0002(SP)
z = x * y;
return 0;
}
x05f4
x05f6
x05f8
x05fa
x05fc
x05fe
x0600
x05f4
argc (r12) x05f6
argv (r13) x05f8
x
x05fa
y
x05fc
z
x05fe
ret adr x0600
Stack
SP
0x8040:
0x8044:
0x8048:
0x804c:
0x8052:
0x8058:
0x805c:
0x8060:
0x8064:
0x8068:
0x806a:
0x806e:
main:
8031 000A
4D81 0002
4C81 0000
40B1 0007 0004
40B1 0005 0006
411C 0004
411D 0006
12B0 80DA
4C81 0008
430C
5031 000A
4130
__mpyi:
0x80da: 430E
mpyi_add_loop:
0x80dc: C312
0x80de: 100C
0x80e0: 2801
0x80e2: 5D0E
shift_test_mpyi:
0x80e4: 5D0D
0x80e6: 930C
0x80e8: 23F9
0x80ea: 4E0C
0x80ec: 4130
SUB.W
MOV.W
MOV.W
MOV.W
MOV.W
MOV.W
MOV.W
CALL
MOV.W
CLR.W
ADD.W
RET
#0x000a,SP
R13,0x0002(SP)
R12,0x0000(SP)
#0x0007,0x0004(SP)
#0x0005,0x0006(SP)
0x0004(SP),R12
0x0006(SP),R13
#__mpyi
R12,0x0008(SP)
R12
#0x000a,SP
CLR.W
R14
CLRC
RRC
JLO
ADD.W
R12
(shift_test_mpyi)
R13,R14
RLA.W
TST.W
JNE
MOV.W
RET
R13
R12
(mpyi_add_loop)
R14,R12
13
Example: Operators
int inGlobal;
void main(void)
{
int outLocal;
int inLocalA;
int inLocalB;
outLocal = inGobal+inLocalA+inLocalB;
return;
}
Symbol
Table
14
void main(void)
{
int c, a, b, r;
switch (c)
{
case '+':
r = a + b;
break;
#0x0006,SP
0x0002(SP),R15
&inGlobal,R15
0x0004(SP),R15
R15,0x0000(SP)
#0x0006,SP
case '-':
r = a - b;
break;
Identifier
Type
Scope
inGlobal
int
Static
absolute
global
inLocalA
int
Auto
2(SP)
main
inLocalB
int
Auto
4(SP)
main
outLocal
int
Auto
0(SP)
main
case '*':
r = a * b;
break;
default:
printf("\nInvalid!");
break;
}
}
15
main:
0x9614: 8031
0x9618: 3C1D
C$L1:
0x961a: 411F
0x961e: 511F
0x9622: 4F81
0x9626: 3C20
C$L2:
0x9628: 411F
0x962c: 811F
0x9630: 4F81
0x9634: 3C19
C$L3:
0x9636: 411C
0x963a: 411D
0x963e: 12B0
0x9642: 4C81
0x9646: 3C10
C$L4:
0x9648: 40B1
0x964e: 12B0
0x9652: 3C0A
C$L5:
0x9654: 411F
0x9658: 803F
0x965c: 27EC
0x965e: 831F
0x9660: 27DC
0x9662: 832F
0x9664: 27E1
0x9666: 3FF0
C$L6:
0x9668: 5031
0x966c: 4130
000A
SUB.W
JMP
#0x000a,SP
(C$L5)
0006
0004
0008
MOV.W
ADD.W
MOV.W
JMP
0x0006(SP),R15
0x0004(SP),R15
R15,0x0008(SP)
(C$L6)
0004
0006
0008
MOV.W
SUB.W
MOV.W
JMP
0x0004(SP),R15
0x0006(SP),R15
R15,0x0008(SP)
(C$L6)
0004
0006
9C98
0008
MOV.W
MOV.W
CALL
MOV.W
JMP
0x0004(SP),R12
0x0006(SP),R13
#__mpyi
R12,0x0008(SP)
(C$L6)
A016 0000
97C0
MOV.W
CALL
JMP
#0xa016,0x0000(SP)
#lcd_printf
(C$L6)
0002
002A
MOV.W
SUB.W
JEQ
DEC.W
JEQ
DECD.W
JEQ
JMP
0x0002(SP),R15
#0x002a,R15
(C$L3)
R15
(C$L1)
R15
(C$L2)
(C$L4)
000A
ADD.W
RET
#0x000a,SP
16
LOOP:
DONE:
MSG:
sub #2,sp
mov #7,0(sp)
; int a = 7;
cmp #0,0(sp)
jeq DONE
mov 0(sp),r12
add #'0',r12
call #PUTC
mov #10,r12
call #PUTC
sub #1,0(sp)
jmp LOOP
; while (a)
; {
;
printf("%c\n", a + '0');
mov #MSG,r12
call #PUTS
...
False
Test
True
Body
;
a--;
; }
DONE:
; printf("All done...\n");
MSG:
mov 0(sp),r12
add #'0',r12
call #PUTC
mov #10,r12
call #PUTC
sub #1,0(sp)
jne LOOP
mov #MSG,r12
call #PUTS
...
; int a = 7;
; do {
;
printf("%c\n", a + '0');
Body
;
a--;
; } while (a);
True
; printf("All done...\n");
False
17
DONE:
MSG:
sub #2,sp
; int a;
mov #0,0(sp)
bit #-1,0(sp)
jeq DONE
mov 0(sp),r12
add #'0',r12
call #PUTC
mov #10,r12
call #PUTC
add #1,0(sp)
cmp #10,0(sp)
jl LOOP
; {
mov #MSG,r12
call #PUTS
...
Test
Example:
int func(a, b, c, d, e, f)
{
int x, y, z;
x = 1;
y = 2;
z = 3;
return a+b+c+d+e+f+x+y+z;
}
int main()
{
func(10, 20, 30, 40, 50, 60);
return 0;
}
Init
; printf("All done...\n");
18
Example: Functions
printf("%c\n", a + '0');
; }
Test
False
f
e
True
z
y
x
d
c
b
SP a
Body
Re-init
19
60
50
Return adr
3
2
1
40
30
20
10
0x0012(SP)
0x0010(SP)
0x000c(SP)
0x000a(SP)
0x0008(SP)
0x0006(SP)
0x0004(SP)
0x0002(SP)
0x0000(SP)
main:
0x8762:
0x8764:
0x876a:
0x8770:
0x8774:
0x8778:
0x877c:
0x8780:
0x8784:
0x8786:
0x8788:
0x853c:
0x8540:
0x8544:
0x8548:
0x854c:
0x8550:
0x8554:
0x8558:
0x855e:
0x8562:
0x8564:
0x8568:
0x856c:
0x8570:
0x8574:
0x8578:
0x857c:
0x8580:
0x8584:
8221
40B1 0032 0000
40B1 003C 0002
403C 000A
403D 0014
403E 001E
403F 0028
12B0 853C
430C
5221
4130
func:
8031 000E
4F81 0006
4E81 0004
4D81 0002
4C81 0000
4391 0008
43A1 000A
40B1 0003 000C
411C 0002
512C
511C 0004
511C 0006
511C 0010
511C 0012
511C 0008
511C 000A
511C 000C
5031 000E
4130
SUB.W
MOV.W
MOV.W
MOV.W
MOV.W
MOV.W
MOV.W
CALL
CLR.W
ADD.W
RET
#4,SP
#0x0032,0x0000(SP)
#0x003c,0x0002(SP)
#0x000a,R12
#0x0014,R13
#0x001e,R14
#0x0028,R15
#func
R12
#4,SP
SUB.W
MOV.W
MOV.W
MOV.W
MOV.W
MOV.W
MOV.W
MOV.W
MOV.W
ADD.W
ADD.W
ADD.W
ADD.W
ADD.W
ADD.W
ADD.W
ADD.W
ADD.W
RET
#0x000e,SP
R15,0x0006(SP)
R14,0x0004(SP)
R13,0x0002(SP)
R12,0x0000(SP)
#1,0x0008(SP)
#2,0x000a(SP)
#0x0003,0x000c(SP)
0x0002(SP),R12
@SP,R12
0x0004(SP),R12
0x0006(SP),R12
0x0010(SP),R12
0x0012(SP),R12
0x0008(SP),R12
0x000a(SP),R12
0x000c(SP),R12
#0x000e,SP
20
int main()
{
int array[10];
int x;
x = array[3] + 1;
array[6] = 5;
return 0;
array[0]
array[1]
array[2]
array[3]
array[4]
array[5]
array[6]
array[7]
array[8]
array[9]
x
SP
0x0000(SP)
0x0002(SP)
0x0004(SP)
0x0006(SP)
0x0008(SP)
0x000a(SP)
0x000c(SP)
0x000e(SP)
0x0010(SP)
0x0012(SP)
0x0014(SP)
int main()
{
int array[10];
int x;
for (x = 0; x < 10; x++)
{
array[x] = x;
main:
}
0x8040: 8031
0x8044: 4381
return 0;
0x8048: 90B1
}
0x804e: 340D
}
main:
0x87a2:
0x87a6:
0x87a8:
0x87ac:
0x87b0:
0x87b6:
0x87b8:
0x87bc:
8031
431F
511F
4F81
40B1
430C
5031
4130
0016
0006
0014
0005 000C
0016
SUB.W
MOV.W
ADD.W
MOV.W
MOV.W
CLR.W
ADD.W
RET
0x8050:
0x8054:
0x8056:
0x8058:
0x805e:
0x8062:
0x8068:
#0x0016,SP
#1,R15
0x0006(SP),R15
R15,0x0014(SP)
#0x0005,0x000c(SP)
R12
#0x0016,SP
21
int array[10];
int x;
grid[x+1] = grid[x] + 2;
0x86aa:
0x86ae:
0x86b0:
0x86b2:
0x86b4:
0x86b6:
0x86ba:
0x86bc:
0x86be:
0x86c0:
411F 0014
5F0F
510F
432E
5F2E
411F 0014
5F0F
532F
510F
4E8F 0000
MOV.W
RLA.W
ADD.W
MOV.W
ADD.W
MOV.W
RLA.W
INCD.W
ADD.W
MOV.W
array[0]
array[1]
array[2]
array[3]
array[4]
array[5]
array[6]
array[7]
array[8]
array[9]
x
0x806a:
0x806c:
0x8070:
0016
0014
000A 0014
SUB.W
CLR.W
CMP.W
JGE
C$DW$L$main$2$B, C$L1:
411F 0014
MOV.W
5F0F
RLA.W
510F
ADD.W
419F 0014 0000
MOV.W
5391 0014
INC.W
90B1 000A 0014
CMP.W
3BF3
JL
C$L2, C$DW$L$main$2$E:
430C
CLR.W
5031 0016
ADD.W
4130
RET
array[0]
array[1]
array[2]
array[3]
array[4]
array[5]
array[6]
array[7]
array[8]
array[9]
x
0x0000(SP)
0x0002(SP)
0x0004(SP)
0x0006(SP)
0x0008(SP)
0x000a(SP)
0x000c(SP)
0x000e(SP)
0x0010(SP)
0x0012(SP)
0x0014(SP)
#0x0016,SP
0x0014(SP)
#0x000a,0x0014(SP)
(C$DW$L$main$2$E)
0x0014(SP),R15
R15
SP,R15
0x0014(SP),0x0000(R15)
0x0014(SP)
#0x000a,0x0014(SP)
(C$L1)
R12
#0x0016,SP
22
0x0000(SP)
0x0002(SP)
0x0004(SP)
0x0006(SP)
0x0008(SP)
0x000a(SP)
0x000c(SP)
0x000e(SP)
0x0010(SP)
0x0012(SP)
0x0014(SP)
int array[10];
int x;
int main()
{
for (x = 0; x < 10; x++)
{
array[x] = x;
main:
}
0x806a: 4382
return 0;
0x806e: 90B2
0x8074: 340C
}
0x0014(SP),R15
R15
SP,R15
#2,R14
@R15,R14
0x0014(SP),R15
R15
R15
SP,R15
R14,0x0000(R15)
0x8076:
0x807a:
0x807c:
0x8082:
0x8086:
0x808c:
0x808e:
0x8090:
23
0214
000A 0214
CLR.W
CMP.W
JGE
C$DW$L$main$2$B, C$L1:
421F 0214
MOV.W
5F0F
RLA.W
429F 0214 0200
MOV.W
5392 0214
INC.W
90B2 000A 0214
CMP.W
3BF4
JL
C$L2, C$DW$L$main$2$E:
430C
CLR.W
4130
RET
&x
#0x000a,&x
(C$DW$L$main$2$E)
&x,R15
R15
&x,0x0200(R15)
&x
#0x000a,&x
(C$L1)
R12
24