1
ARM编程实例
Example1/Example1.DOC
; 例一:数据块拷贝,利用LDR/STR指令
; 项目名:Example1.mcp,文件名:Example1.s ——————————————————————————————————AREA Block, CODE, READONLY
num EQU 10
ENTRY
start
LDR R0, =src
LDR R1, =dst
MOV R2, #num
blockcopy
LDR R3, [R0], #4
STR R3, [R1], #4
SUBS R2, R2, #1
BNE blockcopy
B .
AREA BlockData, DATA, READWRITE
src DCD 0,1,2,3,4,5,6,7,8,9
dst SPACE 10*4
END
Example2/Example2.DOC
; 例二:数据块拷贝,利用LDM/STM指令
; 项目名:Example2.mcp,文件名:Example2.s ——————————————————————————————————AREA Block, CODE, READONLY
num EQU 20
ENTRY
start
LDR R0, =src
2
LDR R1, =dst
MOV R2, #num
MOV SP, #0x400
blockcopy
MOVS R3, R2, LSR #3
BEQ copywords
STMFD SP!, {R4-R11}
octcopy
LDMIA R0!, {R4-R11}
STMIA R1!, {R4-R11}
SUBS R3, R3, #1
BNE octcopy
LDMFD SP!, {R4-R11}
copywords
ANDS R2, R2, #7
BEQ stop
wordcopy
LDR R3, [R0], #4
STR R3, [R1], #4
SUBS R2, R2, #1
BNE wordcopy
stop
B .
AREA BlockData, DATA, READWRITE
src DCD 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9
dst SPACE 20*4
END
Example3/Example3.DOC
;例三:ADR伪指令
;项目名:Example3.mcp,文件名:Example3.s ——————————————————————————————————
3
—————
AREA adrlabel1, CODE, READONLY
ENTRY
start
BL func
B .
LTORG
func
ADR R0, start
ADR R1, DataArea
;ADR R2, DataArea+4300
ADRL R3, DataArea+4300
MOV PC, LR
DataArea
SPACE 8000
END
Example4/Example4.DOC
;例四:LDR伪指令
;项目名:Example4.mcp,文件名:Example4.s ———————————————————————————————————————
AREA LDRlabel1, CODE, READONLY
ENTRY
start
BL func1
BL func2
B .
func1
LDR R0, =start
LDR R1, =Darea+12
LDR R2, =Darea+6000
4
MOV PC, LR
LTORG
func2
LDR R3, =Darea+6000
LDR R4, =Darea+6004
MOV PC, LR
Darea
SPACE 8000
END
Example5/Example5.DOC
;例五:利用跳转表实现程序跳转
;项目名:Example5.mcp,文件名:Example5.s ———————————————————————————————————————
AREA Jump, CODE, READONLY
num EQU 2
ENTRY
start
MOV R0, #0
MOV R1, #3
MOV R2, #2
BL arithfunc
B .
arithfunc
CMP R0, #num
MOVHS PC, LR
ADR R3, JumpTable
LDR PC, [R3,R0,LSL #2]
JumpTable
DCD DoAdd
DCD DoSub
5
DoAdd
ADD R0, R1, R2
MOV PC, LR
DoSub
SUB R0, R1, R2
MOV PC, LR
END
Example6/Example6.DOC
;例六:基于S3C4510B的串行通信程序
;项目名:Example6.mcp,文件名:Example6.s ———————————————————————————————————————
;Define Special Function Register
IOPMOD EQU 0x3FF5000
IOPDATA EQU 0x3FF5008
UARTLCON0 EQU 0x3FFD000
UARTCONT0 EQU 0x3FFD004
UARTSTAT0 EQU 0x3FFD008
UTXBUF0 EQU 0x3FFD00C
UARTBRD0 EQU 0x3FFD014
AREA Init, CODE, READONLY
ENTRY
;LED Display
LDR R1, =IOPMOD
LDR R0, =&ff
STR R0, [R1]
LDR R1, =IOPDATA
LDR R0, =&ff
STR R0, [R1]
6 ;UART0 line control register
LDR R1, =UARTLCON0
LDR R0, =0x03
STR R0, [R1]
;UART0 control regiser
LDR R1, =UARTCONT0
LDR R0, =0x9
STR R0, [R1]
;UART0 baud rate divisor regiser
;Baudrate=19200,对应于50MHz的系统工作频率
LDR R1, =UARTBRD0
LDR R0, =0x500
STR R0, [R1]
;Print the messages!
LOOP
LDR R0, =Line1
BL PrintLine
LDR R0, =Line2
BL PrintLine
LDR R0, =Line3
BL PrintLine
LDR R0, =Line4
BL PrintLine
LDR R1, =0x7FFFFF
LOOP1
SUBS R1, R1, #1
BNE LOOP1
B LOOP
;Print line
7
PrintLine
MOV R4, LR
MOV R5, R0
Line
LDRB R1, [R5], #1
AND R0, R1, #&FF
TST R0, #&FF
MOVEQ PC, R4
BL PutByte
B Line
PutByte
LDR R3, =UARTSTAT0
LDR R2, [R3]
TST R2, #&40
BEQ PutByte
LDR R3, =UTXBUF0
STR R0, [R3]
MOV PC, LR
Line1 DCB &A, &D, "0123456789*", 0
Line2 DCB &A, &D, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0
Line3 DCB &A, &D, "abcdefghijklmnopqrstuvwxyz.",0
Line4 DCB &A, &D, 0
END
3、存储器从0x400000开始的100个单元中存放着ASCII码,编写程序,将其所有的小写字母转换成大写字母,对其它的ASCII码不做变换。
解:
MOV R0,#0x400000
MOV R1,#0
LP
LDRB R2,[R0,R1]
CMP R2,#0x61
BLO NEXT
CMP R2,#0x7B ;0x61---0x7A为小写字母的ASC
SUBLO R2, R2,#0x20
8
STRBLO R2,[R0,R1]
NEXT
ADD R1, R1,#1
CMP R1,#100
BNE LP
8、编写一简单ARM汇编程序段,实现1+2+…+100的运算。
解:
MOV R2,#100
MOV R1,#0
LOOP
ADD R1,R1,R2 ;R1中为累加和
SUBS R2,R2,#1 ;R2控制循环
BNE LOOP
4、编写程序,比较存储器中0x400000和0x400004两无符号字数据的大小,并且将比较结果存于0x400008的字中,若两数相等其结果记为0,若前者大于后者其结果记为1,若前者小于后者其结果记为-1。
解:
MOV R0,#0x400000
LDR R1,[R0] ;取第1个数
LDR R2,[R0,#4] ;取第2个数
CMP R1,R2 ;两个数相比较
MOVHI R1,#1 ;R1大
MOVLO R1,# -1 ;R1小
MOVEQ R1,#0 ;两个数相等
STR R1,[R0,#8]
7、编写一程序,存储器中从0x400200开始有一个64位数。(1)将取反,再存回原处;(2)求其补码,存放到0x400208处。
解:
LDR R0,=0x400200
LDR R2,=0xFFFFFFFF
LDR R1,[R0] ;取低32位数
EOR R1,R1,R2 ;取反
STR R1,[R0] ;存低32位反码
ADDS R1,R1,#1 ;又加1为求补
STR R1,[R0,#8] ;存低32位补码
LDR R1,[R0,#4] ;取高32位数
EOR R1,R1,R2 ;取反
STR R1,[R0,#4] ;存高32位反码
9
ADC R1,R1,#0 ;高32位求补
STR R1,[R0,#12] ;存高32位补码
Example7Example7.OC
例七:汇编语言与C/C++的混和编程
项目名:Example7.mcp
文件名:Example7_asm.s
文件名:Example7_c.c ———————————————————————————————————————
;Example7_asm.s
AREA Asm_C, CODE, READONLY
ENTRY
LDR SP,=0x4000
IMPORT __main
BL __main
B .
END
———————————————————————————————————————
#include
int main()
{
printf("Hello world\n");
return 0;
}
4.4 系统的初始化过程
◆初始化代码直接对ARM微处理器内核及硬件控制器编程,多采用汇编语
言编程,初始化代码一般应包含如下典型任务:
●定义程序入口点
●设置异常向量;
●初始化存储器系统;
10
●初始化堆栈指针寄存器;
●初始化临界I/O设备;
●初始化C代码的运行环境;
●改变处理器的运行模式和状态;
●使能中断;
●进入C代码运行