1.首先说明一下标号( lable)在ARM汇编语言中的含义:
例如:
WatchDog
ldrr4,=WTCONldrpc,=HandelerSWI
该段代码中WatchDog为标号,表示的是指令ldr r4,=WTCON的地址,既WatchDog的值为0x30000024。
以下为该段代码反汇编之后的代码:
0x30000024 [0xe3a04453] mov r4, #0x53000000 ;0x30000028 [0xe59ff018] ldr pc, 0x30000048 ; = #0x3000002
从左到右以此为 链接之后的地址、机器码、指令,分号后注释。
2.LDR指令(不是LDR伪指令)的作用:
以ldr r1, 0x30000048为例说明,表示将地址为0x30000048处的数据加载到r1寄存器中。
3.LDR指令的一些用法:
(1)
WatchDog
ldrr4,=WTCONldrpc,=HandelerSWI
ldrr1,WatchDogldrr2,=WatchDog
以上四条代码的反汇编代指令:
30000024 [0xe3a04453]movr4, #0x5300000030000028 [0xe59ff018] ldr pc, 0x30000048 ; = #0x30000020
30000030 [0xe51f1014] ldr r1, WatchDog ; = #WatchDog30000034 [0xe59f2010] ldr r2, 0x3000004c ; = #0x30000024
执行完后两条语句时r1寄存器值为:0xe3a04453,r2寄存器值为:0x30000024
由于标号表示指令的地址,所以WatchDog表示指令 ldr r4,=WTCON的地址既WatchDog的值为0x30000024。
ldr r1,WatchDog就表示将地址0x30000024处的数据加载至r1寄存器,地址0x30000024处的数据为0xe3a04453,
所以r1寄存器值为:0xe3a04453。 同理ldrr2,0x3000004c将地址0x3000004c处的数据加载至r2寄存器,地址0x3000004c处的数据为0x30000024。
从上面我们可看出在写代码时在标号前面有没有“=”的区别,标号前有“=”表示将标号所表示的值加载至寄存器,而编译器,会自动计算出该标号所在的地址;前面没有“=”表示以标号的值作为地址,将该地址出的数据加载至寄存器。在用将地址加载至PC寄存器进行程序条状的时候必须注意他们的区别。
(2)
ldrpc,Reset_Addr
Reset_Addr
DCD Reset_Handeler
Reset_Handeler
ldrpc,=add以上代码的反汇编指令为:
0x30000000[0xe59ff000]ldrpc,Reset_Addr ; = #Reset_Addr
0x30000008[0x30000010]dcd 0x30000010
0x30000018[0xe59ff024]ldrpc,0x30000044; = #0x3000002c
从左到右以此为 链接之后的地址、机器码、指令,分号后注释。
ldr pc,Reset_Addr就表示将Reset_Addr为值的地址处的数据加载至pc寄存器中,
Reset_Addr为标号代表DCD Reset_Handeler指令的地址,故Reset_Addr为0x30000008
而0x30000008地址处的只为多少呢?由DCD数据定义指令知道在0x30000008地址处的值
为: Reset_Handeler , Reset_Handeler 也为标号,代表 ldr pc,=add指令的地址,故Reset_Handeler 的值为0x30000018。所以地址0x30000008处的值为0x30000018,所以
执行ldr pc,Reset_Addr后pc寄存器的值为:0x30000018。故程序实现了跳转。
(3)
ldrr0,=0x30000054表示将0x30000054加载至r0寄存器中。但其反汇编指令为
0x3000003c[0xe59f400c]ldrr4,0x30000050; = #0x30000054 表示将0x30000050地址处的
数据加载至r0寄存器,而该地址处的数据为0x30000054。
ldrr0,=0x1。该代码的反汇编指令为 mov r0,#0x1
ldr指令和ldr伪指令刚好名字一样,我们写汇编代码一般用的都是ldr伪指令,改指令的用法为:如果后面的数据可以用mov或mvn指令就会被编译成相应的mov或mvn指令,如果不能用mov或mvn则被编译成ldr指令,编译器会把数据存在数据缓冲池,然后加载该数值加载知寄存器。