在ARM(Thumb)汇编语言程序中以程序段为单位组织代码。段可以分为代码段(Code Section)和数据段(Data Section)。一个汇编程序至少应该有一个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译链接时最终形成一个可执行的映像文件。
可执行映像文件的构成:
链接器根据系统默认或用户设定的规则,将各个段安排在存储器中的相应位置。因此源程序中段之间的相对位置与可执行的映像文件中段的相对位置一般不会相同
在ARM汇编语言程序中,子程序的调用一般是通过BL指令来实现的。
bl DELAY ;DELAY即子程序名
...
ldr r0 ,= 0xffff
DELAY:
sub r0,r0,#1 ;r0 = r0 - 1
cmp r0,#0 ;比较r0的值是否等于0
bne DELAY ;不相等则调回去DELAY执行
ldr r1 ,= 0x08
...
(1)子程序执行时需要保存子程序的返回地址存到连接寄存器LR中,以及程序计数器PC指向子程序的入口点。
(2)子程序执行完需要返回,只需要将存放在LR中的返回地址重新拷贝给程序计数器PC。
(3)调用子程序的同时,也可以完成参数的传递和从子程序返回运算的结果,通常可以使用寄存器R0~R3完成
汇编实现字符串的拷贝:
编译环境:Keil4
area init,code,readonly
entry
ldr r0,= datablock1 ;获取字符串的地址存到r0中
ldr r2,= datablock2 ;获取分配的大小为100的内存单元的地址存到r2中
cat
ldrb r1,[r0],#1 ;取出1字节的数据存到r1,r0地址加1
strb r1,[r2],#1 ; 将取出的1字节数据存到r2,r2地址加1
cmp r1, #0 ;比较取出的字符串字符是否为'\0'
bne cat ;不是则继续拷贝
b .
datablock1
dcb "hello young man!",0
datablock2
space 100 ;分配100大小的内存单元
end ;标识程序结束
获取学生最高成绩:
;init.s
area init,code,readonly ;定义有个名为init的代码段(code) 属性为只读
entry
import getmax
import scores
import maxscore
import numofstudent
; mov r0,#1
; mov r1,#2
; cmp r1,r0
; movhi r0,r1
ldr r2,=scores
ldr r4,=numofstudent
ldrb r5,[r4] ;十个学生
ldrb r0,[r2] ;取出第一个学生的成绩
add r2,r2,#1
sub r5,r5,#1 ;取出了第一个学生,减1
bl getmax
ldr r4,= maxscore
strb r0,[r4]
b .
end
;maxoftwo.s
;两个要比较的数在r0,r1中
;比较所得的最大数放在r0当中
area max,code,readonly
import scores ;声明scores来自外部
export getmax ;声明getmax可被外部调用
getmax
ldrb r1,[r2],#1 ;取出第二个学生成绩
sub r5,r5,#1 ;又取出一个学生的成绩,又减1
cmp r1,r0
movhi r0,r1 ; 比较,把成绩高的放到r0中
cmp r5,#0 ;判断十个学生成绩是否取完
bne getmax ;不是继续执行
bx lr
end
;score.s
export scores ;声明可scores被外部调用
export numofstudent
export maxscore
area score ,data,readwrite ;定义数据段,可读可写
scores
dcb 65,78,92,47,77,83,59,93,82,97 ;学生成绩
numofstudent
dcb 10 ; 学生人数
maxscore
dcb 0;//存放最高分数
end