指令是在执行阶段发挥作用的,由CPU(Intel、AMD等)来执行。
伪指令是在编译阶段发挥作用的,由汇编器(MASM、TASM等)来解释。
Note汇编版本老于ARMv6T2的处理器的Thumb指令时,ADRL是无效的。
伪指令
语法ADRLRd,label
其中:
cond
是一个可选的条件代码(请参阅条件执行)。
Rd
是要加载的寄存器。
label
表达式,与程序或寄存器相关。有关详细信息,请参阅相对寄存器和程序相对的表达式。
用法ADRL始终汇编为两个32位指令。即使使用单个指令就可完成地址访问,也会生成多余的第二个地址。
如果汇编程序无法将地址构建为两个指令,则它将生成一条错误消息,汇编将失败。有关加载更宽范围地址的信息,请参阅LDR伪指令(另请参阅将常数加载到寄存器)。
ADRL可生成与位置无关的代码,因为地址与程序或寄存器有关。
如果label与程序有关,则其表示的地址必须要与ADRL伪指令在同一汇编程序区域内,请参阅AREA。
如果使用ADRL来为BX或BLX指令生成目标,则当目标中包含Thumb指令时,您就要自己设置地址的Thumb位(位0)。
体系结构和范围可用范围取决于所用的指令集:
ARM
±64KB到字节或半字对齐的地址。
±256KB字节,字对齐地址。
32位Thumb
±1MB字节,字节、半字或字对齐地址。
16位Thumb
ADRL不可用。
上面给出的范围是相对于位于当前指令后的、离当前指令有四个字节(在Thumb代码中)或两个字(在ARM代码中)间隔的点而言的。在ARM和32位Thumb中,如果地址为16字节对齐,或与该点的相对性更高,则相对地址的范围可更大。
将以下项之一加载到寄存器:
一个32位常数值
任何地址。
MOV32始终会生成两个32位指令,即一个MOV、MOVT对。您可利用它加载任何32位常数或访问整个地址空间。
如果用MOV32加载地址,则所生成的代码将与位置有关。
语法MOV32Rd,expr
其中:
cond
是一个可选的条件代码(请参阅条件执行)。
Rd
是要加载数据的寄存器。Rd不可为sp或pc。
expr
可以是下列项之一:
symbol
程序区域中的标签。
constant
任何32位常数。
symbol+constant
标签加上32位常数。
用法MOV32伪指令的主要功能有:
当单个指令中无法生成立即数时,生成文字常数。
将相对于程序的地址或外部地址载入寄存器中。无论链接器将包含MOV32的ELF代码段置于何处,该地址始终有效。
Note
以这种方式加载的地址是在链接时确定的,因此代码不是位置无关的。
如果所引用的标签位于Thumb代码中,则MOV32将会设置该地址的Thumb位(位0)。
体系结构此伪指令在ARMv6T2和ARMv7中的ARM和Thumb状态下均有效。
LDR伪指令
将以下项之一载入寄存器:
一个32位常数值
一个地址。
Note
本节仅介绍LDR伪指令。有关LDR指令的详细信息,请参阅内存访问指令。
有关使用LDR伪指令加载常数的信息,请参阅用LDRRd,=const加载。
语法
LDR{.w}Rt,=[expr|label?expr]
其中:
cond
是一个可选的条件代码(请参阅条件执行)。
.W
是可选的指令宽度说明符。
Rt
是要加载的寄存器。
expr
取值为一个数值常数:
如果expr的值位于范围内,则汇编程序将会生成一个MOV或MVN指令。
如果expr的值不在MOV或MVN指令的范围内,则汇编程序会将常数放入文字池中,并会生成一个相对于程序的LDR指令,该指令可从文字池中读取此常数。
label?expr
是一个与程序相关的表达式或外部表达式。汇编程序会将label?expr的值放入文字池中,并会生成一个与程序有关的LDR指令,该指令可从文字池中加载该值。
如果label?expr是一个外部表达式,或未包含在当前代码段内,则汇编程序将会在目标文件中放入一个链接器重新定位指令。链接器将在链接时生成该地址。
如果label?expr是一个局部标签(请参阅局部标签),则汇编程序会在目标文件中放入一个链接器重新定位指令,并会为该局部标签生成一个符号。该地址将在链接时生成。如果局部标签引用了Thumb代码,则还会设置该地址的Thumb位(位0)。
Note
在RVCT2.2中,没有对地址的Thumb位进行设置。如果此设置会影响您的代码,则请使用命令行选项??untyped_local_labels迫使汇编程序在引用Thumb代码中的标签时不设置Thumb位。
用法
LDR伪指令的主要功能如下:
当立即数由于超出了MOV和MVN指令的范围,而不能被移入寄存器中时,生成文字常数。
将相对于程序的地址或外部地址载入寄存器中。无论链接器将包含LDR的ELF代码段置于何处,该地址始终有效。
pc到文字池中的值的偏移量必须小于±4KB(ARM、32位Thumb?2),或在0到+1KB(Thumb、16位Thumb?2)范围内。您必须确保有一个满足范围要求的文字池。有关详细信息,请参阅LTORG。
如果所引用标签在Thumb代码中,LDR伪指令将会设置label?expr的Thumb位(位0)。
有关如何使用LDR的详细说明,以及有关MOV和MVN的详细信息,请参阅将常数加载到寄存器。
Thumb代码中的LDR
对于ARMv6T2及更高版本的Thumb代码,您可以使用.W宽度说明符强制LDR生成32位指令。LDR.W始终生成32位指令,即使利用16位MOV就可完成常数的加载,或在16位pc相对载入范围内有文字池。
如果在第一次汇编时,汇编程序尚不知道常数值的相关信息,则不带.W的LDR将会在Thumb代码中生成16位指令,即使这会导致对于可在32位MOV或MVN指令中生成的常数,会通过16位pc相对加载来完成其加载。但是,如果在第一次汇编时汇编程序就已经知道了该常数,并且该常数可以通过32位MOV或MVN指令生成,则将会使用MOV或MVN指令。
LDR伪指令不会生成16位标记设置MOV指令。可使用??diag_warning1727汇编程序命令行选项来检查是否使用了16位指令。
有关如何在不利用文字池加载的情况下来生成常数或地址的信息,请参阅MOV32伪指令。
示例
LDRr3,=0xff0;loads0xff0intor3
;=>MOV.Wr3,#0xff0
LDRr1,=0xfff;loads0xfffintor1
;=>LDRr1,[pc,offset_to_litpool]
;...
;litpoolDCD0xfff
LDRr2,=place;loadstheaddressof
;placeintor2
;=>LDRr2,[pc,offset_to_litpool]
;...
伪指令符(常数或表达式)
其中:
1、伪指令符是伪指令的名称
2、常数或表达式是伪指令的参数,括号表示可有可无
51单片机最常用的伪指令如下:
(1)起始(Origin)伪指令
标号:ORGnn
功能:定义程序或数据块的起始地址。指示此语句后面的程序或数据块以nn为起始地址连续存放在程序存储器中。
例如:
ORG2000H
MOVA,20H
…
ORG伪指令规定了程序的起始地址从2000H开始,即该程序的第一条指令“MOVA,20H”从地址2000H开始存放。)
(2)字节定义(DefineByte)伪指令
标号:DB(字节常数或字符或表达式)
功能:指示在程序存储器中以标号为起始地址的单元里存放的数为字节数据(8位二进制数)。
例如:
OGR100H
TAB1:DB0FFH,'C',16,?1
从TAB1开始的地址单元依次存放0FFH、43H、10H、0FFH
其中,TAB1=100H(ORG指定);C的ASCII码为43H;十进制16的十六进制为10H,-1的补码为FFH
(3)字定义(DefineWord)伪指令
标号:DW(字常数或表达式)
功能:指示在程序存储器中以标号为起始地址的单元里存放的数为字数据(16位的二进制数)。
例如:
OGR100H
TAB3:DW5678H,10
其中,TAB3=100H(ORG指定);ROM中的存放情况为:(100H)=56H、(101H)=78H、(102H)=00H、(103H)=0AH
(4)保留字节(DefineStorage)伪指令
标号:DS(数值表达式)
功能:指示在程序存储器中保留以标号为起始地址
的若干字节单元,其单元个数由数值表达式指定。
例如:
TAB2:DS16;从TAB2地址开始保留16个存储单元
(5)等值(Equate)伪指令
标号:EQU(数值表达式)
功能:表示EQU两边的量等值,用于为标号或标识符赋值。
例如:
X1EQU2000H
X2EQU0FH
…
MAIN:
MOVDPTR,#X1;DPTR=2000H
ADDA,#X2;A=A+0FH
(6)位定义伪指令
标号:BIT(位地址)
功能:同EQU指令,不过定义的是位操作地址。
例如:
ENABITP2.2
(7)汇编结束伪指令
标号:END
功能:指示源程序段结束。END指令放在程序的最后。若将END放在程序中间,那么对于END后面的指令,汇编程序将不对其进行汇编。一个汇编语言源程序仅允许使用一个END伪指令。
生成无体系结构定义的指令。执行未定义指令会引发未定义指令异常。请让无体系结构定义的指令保持在未定义状态。
语法
UND{.w}{#expr}
其中:
cond
是一个可选的条件代码(请参阅条件执行)。对于ARM代码或16位Thumb代码,不允许此伪指令使用cond。
W
是可选的指令宽度说明符。
expr
取值为一定范围内的数值常数:
对于ARM代码,为0-65535
对于32位Thumb代码,为0-4095
对于16位Thumb代码,为0-255。
如果省略了expr,则使用的值为0。
Thumb代码中的UND
对于ARMv6T2及更高版本处理器的Thumb代码,您可利用.W宽度说明符强制UND生成32位指令。UND.W始终生成32位指令,即使expr在0-255范围之内。
反汇编
此伪指令生成的编码将反汇编为DCI。
;litpoolDCDplace
大学汇编课本中主要介绍的伪指令:
(1)assume段寄存器名:段名
假设(将段与CPU中段寄存器联系起来)
(2)段名segment开始
段名ends结束(成对出现)
(3)ends(整个程序结束)