关于伪指令的概念,在小生其他博文中已经给予详细说明,这里不再解释;
ARM汇编中的伪指令有4条:
LDR 大范围地址读取伪指令(并不是ARM指令中的LDR指令)
ADRL 中等范围地址读取伪指令
ADR 小范围地址读取伪指令
NOP 空操作伪指令
(1)LDR (大范围读取)
格式:LDR {条件} 寄存器Rm,=addr
功能:加载32为立即数或地址值到指定寄存器Rm。LDR常用于加载寻片外围功能部件的寄存器地址(32位立即数),以实现各种控制操作。
addr 有两种表达方式:32位立即数或者PC
栗子:
LDR Rm,=#0x12345678
LDR Rm,=DATA_BUF + 60
寄存器加载外围功能部件寄存器地址(32位立即数)栗子:
……
LDR R0,=IOPIN ;伪指令,加载GPIO的寄存器IOPIN的地址
LDR R1,[R0] ;ARM指令,读取IOPIN寄存器的值
……
LDR R0,=IOSET ;伪指令,加载GPIO的寄存器IOSET地址
LDR R1,=0x00500500 ;伪指令,加载立即数到R1
STR R1,[R0] ;ARM指令,IOSET==0x00500500
……
注意:
若加载的常常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令。否则汇编指令将会把常量放在文子池中,并使用一条程序相对偏移的LDR指令从文子池读出常量;
- 从PC到文子池的偏移量必须小于4KB
- 与ARM指令LDR(加载)相比,伪指令的LDR的参数有=号;
**重点来了:**关于LDR指令和LDR伪指令的区别,请参考这位同志的博客:
http://www.cnblogs.com/simonshi/archive/2010/04/23/1718687.html
(2)ADRL(中等范围读取)
格式:ADRL{条件} 寄存器Rm,addr
功能:将基于PC偏移地址值或基于寄存器相对偏移地址值读取到寄存器中。addr是地址表达式。当地址值是非对其时,取值范围是-64KB到64KB;当地址值是字对齐时,取值范围-256KB到256KB。
特点:在汇编编译源程序时,ADRL伪指令会被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。
下面是使用ADRL加载地址的栗子:
……
ADR LR , RETURN1 ;设置返回地址
ADRL R1,Thumb_sub + 1 ;取得Thumb子程序入口地址,且R1的0置1
BX R1 ;调用Thumb子程序,并切换处理器状态
RETURN1
……
CODE16
Thumb_sub MOV R1 , #10
……
(3)ADR(小范围读取)
格式:ADR{条件} 寄存器Rm,addr
功能:将PC偏移地址值或寄存器偏移地址值传送到寄存器中。
addr是地址表达式,当地址值是非字对齐时,取值范围是-255到255Byte,字对齐时取值范围是-1020到1020Byte。
特点:汇编编译源程序时,ADR伪指令被替换成一条ADD或SUB指令来实现该ADR伪指令的功能,如果不能用一条指令来实现,则会产生错误,编译失败;
下面是ADR伪指令,实现查表功能:
……
ADR R0,ADDR_TAB ;将ADDR_TAB表地址(数组地址)传递给R0;
LDRB R1,[R0,R2] ;使用R2作为参数进行查表
……
ADDR_TAB DCB 0xA0 ,0xF8,0x80,0x48,0xE0,0x4F,0xA3,0xD2
(4)NOP空操作伪指令
格式:NOP
功能:延时;
特点:NOP伪指令在编译时将会被替代成ARM中的空操作,比如MOV R0,R0指令等;