伪指令:用于告诉汇编程序如何进行汇编的指令,它既不控制机器的操作也不被汇编成机器代码,只能为汇编程序所识别并指导汇编如何进行。
在汇编语言中,指令和伪指令的本质区别
汇编语言中,指令一般用大写,是机器码的助记符号,与一定的机器码相对应。而伪指令(汇编命令和宏命令等)通常用"."开头,小写。伪指令语句除定义的具体数据要生成目标代码外,其他均没有对应的目标代码,指示引导汇编语言在汇编过程做一些操作,如对符号地址(标号与变量)给予数值地址,对符号赋予具体数值,将一些数据放入制定的存储单元,在存储器留一些空单元等等。
详细地说:[指令语句]
每一条指令语句在源程序汇编时都要产生可供计算机执行的指令代码(即目标代码),所以这种语句又叫可执行语句。每一条指令语句表示计算机具有的一个基本能力,如数据传送,两数相加或相减,移位等,而这种能力是在目标程序(指令代码的有序集合)运行时完成的,是依赖于汁算机内的中央处理器(CPU)、存储器、I/O接口等硬件设备来实现的。
[伪指令语句]
伪指令语句是用于指示汇编程序如何汇编源程序,所以这种语句又叫命令语句。例如源程序中的伪指令
语句告诉汇编程序:该源程序如何分段,有哪些逻辑段在程序段中哪些是当前段,它们分别由哪个段寄存器指向;定义了哪些数据,存储单元是如何分配的等等。伪指令语句除定义的具体数据要生成目标代码外,其他均没有对应的目标代码。伪指令语句的这些命令功能是由汇编程序在汇编源程序时,通过执行一段程序来完成的,而不是在运行目标程序时实现的。
ADRL 伪指令
将相对于程序或相对于寄存器的地址载入寄存器中。与 ADR 指令相似。ADRL 所加载的地址比 ADR 所加载的地址更宽,因为它可生成两个数据处理指令。
Note
汇编版本老于 ARMv6T2 的处理器的 Thumb 指令时,ADRL 是无效的。
语法
ADRL Rd,label
其中:
cond
是一个可选的条件代码(请参阅条件执行)。
Rd
是要加载的寄存器。
label
表达式,与程序或寄存器相关。有关详细信息,请参阅相对寄存器和程序相对的表达式。
用法
ADRL 始终汇编为两个 32 位指令。即使使用单个指令就可完成地址访问,也会生成多余的第二个地址。
如果汇编程序无法将地址构建为两个指令,则它将生成一条错误消息,汇编将失败。有关加载更宽范围地址的信息,请参阅LDR 伪指令(另请参阅将常数加载到寄存器)。
ADRL 可生成与位置无关的代码,因为地址与程序或寄存器有关。
如果 label 与程序有关,则其表示的地址必须要与 ADRL 伪指令在同一汇编程序区域内,请参阅AREA。
如果使用 ADRL 来为 BX 或 BLX 指令生成目标,则当目标中包含 Thumb 指令时,您就要自己设置地址的 Thumb 位(位 0)。
体系结构和范围
可用范围取决于所用的指令集:
ARM
±64KB 到字节或半字对齐的地址。
±256K B 字节,字对齐地址。
32 位 Thumb
±1MB 字节,字节、半字或字对齐地址。
16 位 Thumb
ADRL 不可用。
上面给出的范围是相对于位于当前指令后的、离当前指令有四个字节(在 Thumb 代码中)或两个字(在 ARM 代码中)间隔的点而言的。在 ARM 和 32 位 Thumb 中,如果地址为 16 字节对齐,或与该点的相对性更高,则相对地址的范围可更大。
MOV32 伪指令
将以下项之一加载到寄存器:
一个 32 位常数值
任何地址。
MOV32 始终会生成两个 32 位指令,即一个 MOV、MOVT 对。您可利用它加载任何 32 位常数或访问整个地址空间。
如果用 MOV32 加载地址,则所生成的代码将与位置有关。
语法
MOV32 Rd, 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 伪指令加载常数的信息,请参阅用 LDR Rd, =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 代码段置于何处,该地址始终有效。
Note
以这种方式加载的地址是在链接时确定的,因此代码不是位置无关的。
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 位指令。LD
R.W 始终生成 32 位指令,即使利用 16 位 MOV 就可完成常数的加载,或在16 位 pc 相对载入范围内有文字池。
如果在第一次汇编时,汇编程序尚不知道常数值的相关信息,则不带 .W 的 LDR 将会在 Thumb 代码中生成 16 位指令,即使这会导致对于可在 32 位 MOV 或 MVN 指令中生成的常数,会通过 16 位 pc 相对加载来完成其加载。但是,如果在第一次汇编时汇编程序就已经知道了该常数,并且该常数可以通过 32 位 MOV 或 MVN 指令生成,则将会使用 MOV 或 MVN 指令。
LDR 伪指令不会生成 16 位标记设置 MOV 指令。可使用 --diag_warning 1727 汇编程序命令行选项来检查是否使用了 16 位指令。
有关如何在不利用文字池加载的情况下来生成常数或地址的信息,请参阅MOV32 伪指令。
示例
LDR r3,=0xff0 ; loads 0xff0 into r3
; => MOV.W r3,#0xff0
LDR r1,=0xfff ; loads 0xfff into r1
; => LDR r1,[pc,offset_to_litpool]
; ...
; litpool DCD 0xfff
LDR r2,=place ; loads the address of
; place into r2
; => LDR r2,[pc,offset_to_litpool]
; ...
UND 伪指令
生成无体系结构定义的指令。执行未定义指令会引发未定义指令异常。请让无体系结构定义的指令保持在未定义状态。
语法
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。
; litpool DCD place
第四节伪指令
伪指令是对汇编起某种控制作用的特殊命令,其格式与通常的操作指令一样,并可加在汇编程序的任何地方,但它们并不产生机器指令。
许多伪指令要求带参数,这在定义伪指令时由“表达式”域指出,任何数值与表达式匀可以作为参数。
不同汇编程序允许的伪指令并不相同,以下所述的伪指令仅适用于MASM51系统,但一些基本的伪指令在大部份汇编程序中都能使用,当使用其它的汇编程序版本时,只要注意一下它们之间的区别就可以了。MASM51中可用的伪指令有:
ORG 设置程序起始地址
END 标志源代码结束
EQU 定义常数
SET 定义整型数
DATA 给字节类型符号定值
BYTE 给字节类型符号定值
WROD 给字类型符号定值
BIT 给位地址取名
ALTNAME 用自定义名取代保留字
DB 给一块连续的存储区装载字节型数据
DW 给一块连续的存储区装载字型数据
DS 预留一个连续的存储区或装入指定字节。
INCLUDE 将一个源文件插入程序中
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论