ARM 中伪指令不是真正的ARM 指令或Thumb 指令,这些伪指令在编译器对源程序进行汇编处理时被替换成相应的ARM 或Thumb 指令序列。 ARM 伪指令包括ADR、ADRL、LDR和NOP;Thumb 伪指令与ARM 伪指令相似,包括ADR、LDR 和NOP,只是它不支持ADRL。
(1)ADR(小范围的地址读取伪指令)
用途:该指令将基于PC 的地址值或基于寄存器的地址值读取到寄存器中。
格式:ADR {cond} register,expr
其中:cond 为可选的指令执行的条件;register 为目标寄存器;expr 为基于PC 或者基于寄存器的地址表达式,其取值范围如下:
①当地址值不是字对齐时,其取值范围为-255 ~255 B。
②当地址值是字对齐时,其取值范围为-1 020 ~1 020 B。
③当地址值是16 字节对齐时,其取值范围将更大。
在处理源程序时,ADR 伪指令通常被编译器替换成一条ADD 指令或SUB 指令,以实现该ADR 伪指令的功能。 如果不能用一条指令来替换,编译器将报告错误。
因为ADR 伪指令中的地址是基于PC 或基于寄存器的相对偏移,所以ADR 读取到的地址为位置无关的地址。 当ADR 伪指令中expr 是基于PC 的偏移地址时,该地址与ADR 伪指令必须在同一个代码段中。
示例:
(2)ADRL(中等范围的地址读取伪指令)
用途:该指令将基于PC 或基于寄存器的地址值读取到寄存器中。 ADRL 伪指令与ADR伪指令的不同之处在于,它可以读取更大范围的地址。 ADRL 伪指令在汇编时,被编译器替换成两条数据处理指令。
格式:ADRL {cond} register,expr
其中:cond 为可选的指令执行的条件;register 为目标寄存器;expr 为基于PC 或基于寄存器的地址表达式,其取值范围如下:
①当地址值不是字对齐时,其取值范围为-64 ~64 KB。
②当地址值是字对齐时,其取值范围为-256 ~256 KB。
③当地址值是16 字节对齐时,其取值范围将更大。
在处理源程序时,ADRL 伪指令被编译器替换成两条合适的数据处理指令,即使一条指令可以完成该伪指令的功能,编译器也将用两条指令来替换该ADRL 伪指令。 如果不能用两条指令来实现ADRL 伪指令的功能,编译器将报告错误。
因为ADRL 伪指令中的地址是基于PC 或基于寄存器的相对偏移,所以ADRL 读取到的地址为位置无关的地址。 当ADRL 伪指令中的地址是基于PC 时,该地址与ADRL 伪指令必须在同一个代码段中,否则链接后可能超出范围。
注意:在汇编Thumb 指令时,ADRL 无效,ADRL 仅用在ARM 代码中。
示例:
本ADRL 伪指令将被编译器替换成下面两条指令(在GNU 环境下)
(3)LDR(大范围的地址读取伪指令)
用途:LDR 伪指令将一个32 位的立即数或一个地址值读取到寄存器中。
格式:LDR {cond} register,=[expr | label-expr]
其中:cond 为可选的指令执行的条件;register 为目标寄存器;expr 为32 位的常量。 编译器将根据expr 的取值情况,如下处理LDR 伪指令:(www.xing528.com)
①当expr 表示的地址值在MOV 或MVN 指令中地址的取值范围以内时,编译器用合适的MOV 或MVN 指令代替该LDR 伪指令。
②当expr 表示的地址值超过了MOV 或MVN 指令中地址的取值范围时,编译器一般将该常数放在数据缓冲区(也称为“文字池”)中,同时用一条基于PC 的LDR 指令读取该常数。
③Label-expr 为基于PC 的地址表达式或外部表达式。
④当Label-expr 为基于PC 的地址表达式时,编译器将label-expr 表示的数值放在数据缓冲区中,同时用一条LDR 指令读取该数值。
⑤当Label-expr 为外部表达式或非当前段的表达式时,汇编编译器将在目标文件中插入链接重定位伪操作,这样链接器将在链接时生成该地址。
LDR 伪指令主要有以下两种用途:
a.当需要读取到寄存器中的数据超过了MOV 及MVN 指令可以操作的范围时,可以使用LDR 伪指令将该数据读取到寄存器中。
b.将一个基于PC 的地址值或外部的地址值读取到寄存器中。 注意,LDR 伪指令处的PC值到数据缓冲区中的目标数据所在的地址的偏移量要小于4 KB,还必须确保在指令范围内有一个文字池。 因为这种地址值在链接时是确定的,所以这种代码不是位置无关的。 (有一些伪指令得到的是当前PC 与标号的相对偏移,所以是位置无关的。 例如,指令LDR R5,constb 是位置无关的)。
示例1:
将0xFF 读取到R1 中。
LDR R1,=0xFF
汇编后将得到:
MOV R1,0xFF
示例2:
将0xFFF 读取到R1 中。
LDR R1,=0xFFF
汇编后将得到:
示例3:
将外部地址ADDR1 读取到R1 中。
LDR R1,=ADDR1
汇编后将得到:
(4)NOP(空操作伪指令)
用途:NOP 伪指令在汇编时将被替换成ARM 中的空操作,比如可能为MOV R0,R0 等。
格式:NOP
NOP 伪指令不影响CPSR 中的条件标志位。 NOP 伪指令在汇编时将会被代替成ARM 的空操作,例如“MOV R0,R0”。 NOP 不能有条件使用。 执行和不执行空操作指令对结果都是一样的,所以不需要有条件执行。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。