1、ARM汇编的格式:在ARM汇编里,有些字符是用来标记的,这些字符要求顶格写;有些伪码是需要成对出现的,例如ENTRY和END,就需要对齐出现,也就是说他们要么都顶格,要么都空相等的空,否则编译器将报错。常量定义需要顶格书写,不然,编译器同样会报错。2、字符串变量的值是一系列的字符,并且使用双引号作为分界符,如果要在字符串中使用双引号,则必须连续使用两个双引号。3、在使用LDR时,当格式是LDR r0,=0x022248,则第二个参数表示地址,即0x022248,同样的,当src变量代表一个数组时,需要将r0寄存器指向src则需要这样赋值:LDR r0,=src当格式是LDR r0,[r2],则第二个参数表示寄存器,我的理解是[]符号表示取内容,r2本身表示一个寄存器地址,取内容候将其存取r0这个寄存器中。4、在语句:CMP r0,#numBHS stop书上意思是:如果r0寄存器中的值比num大的话,程序就跳转到stop标记的行。但是,实际测试的时候,我发现如果r0和num相等也能跳转到stop标记的行,也就是说只要r0小于num才不会跳转。下面就两个具体的例子谈谈ARM汇编(这是我昨天好不容易看懂的,呵呵)。第一个是使用跳转表解决分支转移问题的例程,源代码如下(保存的时候请将文件后缀名改为s):AREA JumpTest,CODE,READONLY
CODE32
numEQU4ENTRY
start
MOVr0,#4
MOVr1,#3
MOVr2,#2
MOVr3,#0
CMPr0,#num
BHSstop
ADRr4,JumpTable
CMPr0,#2
MOVEQr3,#0
LDREQpc,[r4,r3,LSL #2]
CMPr0,#3
MOVEQr3,#1
LDREQpc,[r4,r3,LSL #2]
CMPr0,#4
MOVEQr3,#2
LDREQpc,[r4,r3,LSL #2]
CMPr0,#1
MOVEQr3,#3
LDREQpc,[r4,r3,LSL #2]
DEFAULT
MOVEQr0,#0
SWITCHEND stop
MOVr0,#0x18
LDRr1,=0x20026
SWI0x123456
JumpTable
DCDCASE1
DCDCASE2
DCDCASE3
DCDCASE4
DCDDEFAULT
CASE1
ADDr0,r1, r2
BSWITCHEND
CASE2
SUBr0,r1, r2
BSWITCHEND
CASE3
ORRr0,r1, r2
BSWITCHEND
CASE4
ANDr0,r1, r2
BSWITCHEND
END
程序其实很简单,可见我有多愚笨!还是简要介绍一下这段代码吧。首先用AREA伪代码加上CODE,表明下面引出的将是一个代码段(于此相对的还有数据段DATA),ENTRY和END成对出现,说明他们之间的代码是程序的主体。start段给寄存器初始化。ADRr4, JumpTable一句是将相当于数组的JumpTable的地址付给r4这个寄存器。stop一段是用来是程序退出的,第一个语句“MOV r0,#0x18”将r0赋值为0x18,这个立即数对应于宏angel_SWIreason_ReportException。表示r1中存放的执行状态。语句“LDR r1,=0x20026”将r1的值设置成ADP_Stopped_ApplicationExit,该宏表示程序正常退出。然后使用SWI,语句“SWI 0x123456”结束程序,将CPU的控制权交回调试器手中。 在JumpTable表中,DCD类型的数组包含四个字,所以,当实现CASE跳转的时候,需要将给出的索引乘上4,才是真正前进的地址数。再看一个用汇编实现冒泡排序的例程:AREA Sort,CODE,READONLY
ENTRY
start
MOVr4,#0
LDRr6,=src
ADDr6,r6,#len
outer
LDRr1,=src
inner
LDRr2,[r1]
LDRr3,[r1,#4]
CMPr2,r3
STRGTr3,[r1]
STRGTr2,[r1,#4]
ADDr1,r1,#4
CMPr1,r6
BLTinner
ADDr4,r4,#4
CMPr4,#len
SUBLEr6,r6,#4
BLEouter
stop
MOVr0,#0x18
LDRr1,=0x20026
SWI0x123456
AREAArray,DATA,READWRITE
srcDCD 2,4,10,8,14,1,20
lenEQU 7*4
END
用汇编实现循环需要跳转指令,但是因为ARM系统只有一个CPSR寄存器,所以要实现双重循环还是有些难度。上面这个代码还是有相当大的借鉴意义。程序不难读懂,和C语言的冒泡排序基本思路是完全一样的。
CODE32
numEQU4ENTRY
start
MOVr0,
MOVr1,
MOVr2,
MOVr3,
CMPr0,#num
BHSstop
ADRr4,
CMPr0,
MOVEQr3,
LDREQpc,
CMPr0,
MOVEQr3,
LDREQpc,
CMPr0,
MOVEQr3,
LDREQpc,
CMPr0,
MOVEQr3,
LDREQpc,
DEFAULT
MOVEQr0,
SWITCHEND
MOVr0,
LDRr1,
SWI0x123456
JumpTable
DCDCASE1
DCDCASE2
DCDCASE3
DCDCASE4
DCDDEFAULT
CASE1
ADDr0,
BSWITCHEND
CASE2
SUBr0,
BSWITCHEND
CASE3
ORRr0,
BSWITCHEND
CASE4
ANDr0,
BSWITCHEND
END
程序其实很简单,可见我有多愚笨!还是简要介绍一下这段代码吧。首先用AREA伪代码加上CODE,表明下面引出的将是一个代码段(于此相对的还有数据段DATA),ENTRY
ENTRY
start
MOV
LDR
ADD
outer
LDR
inner
LDR
LDR
CMP
STRGT
STRGT
ADD
CMP
BLT
ADD
CMP
SUBLE
BLE
stop
MOV
LDR
SWI
AREA
src
len
END
用汇编实现循环需要跳转指令,但是因为ARM系统只有一个CPSR寄存器,所以要实现双重循环还是有些难度。上面这个代码还是有相当大的借鉴意义。程序不难读懂,和C语言的冒泡排序基本思路是完全一样的。