Topics to Cover
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
Where are We?
Problems
MSP 430 Microcontroller Basics by Davies
Chapter 3: Development
Chapter 5: Architecture of the MSP430 Processor
Assembly Program Examples in Other Chapters
Algorithms
Language (Program)
Programmable
Machine (ISA) Architecture
Computer Specific
Micro-architecture
Manufacturer Specific
Circuits
Devices
3
Assembler
An assembler
translates a program
into machine code
High Level vs. Assembly
An assembler outputs
an object file as input
to a linker program
An assembly program
is a text file
High Level Languages
More programmer friendly
More ISA independent
Each high-level statement translates to several
instructions in the ISA of the computer
Assembly Languages
Lower level, closer to ISA
Very ISA-dependent
Each instruction specifies a single ISA instruction
Makes low level programming more user friendly
More efficient code
Why Assembly Code?
Assembler Syntax
Allows us to work at a slightly higher level than machine
language.
Allows us to use symbolic names for opcodes
Allows us to use symbolic names for memory locations SUM, PRODUCT
Dont need to know every address of every storage
location.
Calculates addresses for us really a big deal!
Helps to allocate memory locations.
Provides additional error checking
A line can have four fields
label, mnemonic, operand list, and comment
The general syntax is:
{label[:]} mnemonic {operand list} {;comment}
Some line examples are:
.sect ".sysmem
.word 2
.text
Label1: mov r4,r5
.end
var1
;
;
;
;
Data Space
variable var1 declaration
Program Space
move R4 contents to R5
Assembly List File
Assembly Code Example
;*******************************************************************************
;
CS/ECEn 124 Lab 4 - morse.asm: Student Code
;*******************************************************************************
.cdecls C,LIST, "msp430x22x4.h
; include C header
A line in a listing file has four
fields:
Field 1: contains the
source code line counter
Field 2: contains the
section program counter
Field 3: contains the
object code
Field 4: contains the
original source statement.
COUNT
Labels
;
;
WDT_ISR:
Field 1 Field 2 Field 3
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
Watchdog Timer interrupt service routine
xor.b
dec.w
jne
mov.w
xor.b
Comments
#0x20,&P4OUT
&cnt
WDT_exit
#COUNT,&cnt
#0x01,&P1OUT
; pulse buzzer
; decrement counter
.sect
.word
".int10"
WDT_ISR
; MSP430 RESET Vector
; Watchdog ISR
.sect
.word
.end
".reset"
RESET
; MSP430 RESET Vector
; Power Up ISR
reti
; initialize counter
; toggle P1.0
; return from interrupt
Assembler Directives
Example: Operators
Assembly directives are used to specify:
Starting addresses for programs
Starting values for memory locations
Specify the end of program text.
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)
; MSP430 RESET Vector
; Power Up ISR
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
int main(int argc, char* argv[])
{
unsigned int x = 7;
unsigned int y = 5;
unsigned int z;
#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
Example: Control Structures
main:
SUB.W
MOV.W
ADD.W
ADD.W
MOV.W
ADD.W
RET
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
Storage Class Offset
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
Example: Control Structures
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
...
Example: Control Structures
sub #2,sp
mov #7,0(sp)
LOOP:
False
Test
True
Body
;
a--;
; }
DONE:
; printf("All done...\n");
MSG:
.string "All done...\n"
.byte 0
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
.string "All done...\n"
.byte 0
17
Example: Control Structures
LOOP:
DONE:
MSG:
sub #2,sp
; int a;
mov #0,0(sp)
; for (a=0; a<10; a++)
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
.string "All done...\n"
.byte 0
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
Example: Arrays and Pointers
Example: Arrays and Pointers
SP
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
Example: Arrays and Pointers
SP
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
Example: Arrays and Pointers
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