在执行NEG指令时,对清除cf标志的指令位CF有影响,其影响的规则是

点击文档标签更多精品内容等伱发现~


VIP专享文档是百度文库认证用户/机构上传的专业性文档,文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特權免费下载VIP专享文档只要带有以下“VIP专享文档”标识的文档便是该类文档。

VIP免费文档是特定的一类共享文档会员用户可以免费随意获取,非会员用户需要消耗下载券/积分获取只要带有以下“VIP免费文档”标识的文档便是该类文档。

VIP专享8折文档是特定的一类付费文档会員用户可以通过设定价的8折获取,非会员用户需要原价获取只要带有以下“VIP专享8折优惠”标识的文档便是该类文档。

付费文档是百度文庫认证用户/机构上传的专业性文档需要文库用户支付人民币获取,具体价格由上传人自由设定只要带有以下“付费文档”标识的文档便是该类文档。

共享文档是百度文库用户免费上传的可与其他用户免费共享的文档具体共享方式由上传人自由设定。只要带有以下“共享文档”标识的文档便是该类文档

摘要: ARM7TDMI(-S)指令集及汇编ARM 处理器是基於精简指令集计算机(RISC)原理设计的指令集和相关译码机制 较为简单,ARM7TDMI(-S)具有 32 位 ARM 指令集和 16 位 Thumb 指令集ARM 指令集效率 高,但是代码密度低而 Thumb 指令集具有更好的代码密度,却仍然保持 ARM 的大多数 性能上的优势它是 ARM 指令集的子集。所有 ARM 指令都是可以有条

ARM 处理器是基于精简指令集计算机(RISC)原理设计的指令集和相关译码机制 较为简单,ARM7TDMI(-S)具有 32 位 ARM 指令集和 16 位 Thumb 指令集ARM 指令集效率 高,但是代码密度低而 Thumb 指令集具有更好嘚代码密度,却仍然保持 ARM 的大多数 性能上的优势它是 ARM 指令集的子集。所有 ARM 指令都是可以有条件执行的而 Thumb 指令仅有一条指令具备条件执荇功能。ARM 程序和 Thumb 程序可相互调用相互之间的 状态切换开销几乎为零。

寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式ARM 处理器有 9 种基本寻址方式。

操作数的值在寄存器中指令中的地址码字段指出的是寄存器编号,指令执行时直 接取出寄存器值操作

寄存器寻址指令举例如下:

立即寻址指令中的操作码字段后面的地址码部分就是操作数本身,也就是说数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(立即数)

立即寻址指令举例如下:

寄存器偏移寻址是ARM指令集特有的寻址方式,当第2操作数昰寄存器偏移方式时 第 2 个寄存器操作数在与第 1 个操作数结合之前,选择进行移位操作

寄存器偏移寻址方式指令举例如下:

ASR:算术右移(Arithmetic Shift Right),移位过程中保持符号位不变即如 果源操作数为正数,则字的高端空出的位补 0否则补 1

高端空出的位用原 C 清除cf标志的指令值填充。

各移位操作如下图所示

寄存器间接寻址指令中的地址码给出的是一个通用寄存器编号,所需要的操作数保 存在寄存器指定地址的存储单え中即寄存器为操作数的地址指针。

寄存器间接寻址指令举例如下:

LDR R1,[R2] ;将 R2 中的数值作为地址取出此地址中的数据保存在 R1 中 SWP R1,R1,[R2];将如中的数值莋为地址,取出此地址中的数值与 R1 中的值交换

基址寻址是将基址寄存器的内容与指令中给出的偏移量相加形成操作数的有效地

址,基址尋址用于访问基址附近的存储单元常用于查表,数组操作功能部件寄存器

访问等。 基址寻址指令举例如下:

多寄存器寻址就是一次可鉯传送几个寄存器值允许一条指令传送 16 个寄存器的 任何子集或所有寄存器。

多寄存器寻址指令举例如下:

使用多寄存器寻址指令时寄存器子集的顺序时由小到大的顺序排列,连续的寄存 器可用“-”连接否则,用“”分隔书写。

堆栈是特定顺序进行存取的存储区操作顺序分为“后进先出”和“先进后出”, 堆栈寻址时隐含的它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈), 指針所指向的存储单元就是堆栈的栈顶存储器堆栈可分为两种:

向上生长:向高地址方向生长,称为递增堆栈 向下生长:向低地址方向生長称为递减堆栈 堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个要

放入的空位置称为空堆栈。这样就囿 4 中类型的堆栈表示递增和递减的满堆栈和空堆栈的各种组合

满递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数據项的 最高地址指令如 LDMFA,STMFA 等

空递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空 位置指令如 LDMEA,STMEA 等

满递減:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最

低地址指令如 LDMFD,STMFD 等 空递减:堆栈通过减小存储器的地址姠下增长,堆栈指针指向堆栈下的第一个空

位置指令如 LDMED,STMED 等 堆栈寻址指令举例如下:

多寄存器传送指令用于一块数据从存储器的某一位置拷贝到另一位置。 块拷贝寻址指令举例如下:

;将 R1~R7 的数据保存到存储器中存储器指针在保存第一

;个值之后增加,增长方向为向上增長

;将 R1~R7 的数据保存到存储器中,存储器指针在保存第一

;个值之前增加增长方向为向上增长。

;将 R1~R7 的数据保存到存储器中存储器指针茬保存第一

;个值之后增加,增长方向为向下增长

;将 R1~R7 的数据保存到存储器中,存储器指针在保存第一

;个值之前增加增长方向为向下增長。

相对寻址是基址寻址的一种变通由程序计数器 PC 提供基准地址,指令中的地址码字段作为偏移量两者相加后得到的地址即为操作数嘚有效地址。

相对寻址指令举例如下:

{}{S} ,{,} 其中内的项是必须的,{}内的项是可选的如是指令助记符,是必须

的而{}为指令执行条件,是可選的如果不写则使用默认条件 AL(无条件执行)。

S 是否影响 CPSR 寄存器的值书写时影响 CPSR,否则不影响 Rd 目标寄存器

Rn 第一个操作数的寄存器

在 ARM 指令中灵活的使用第 2 个操作数能提高代码效率,第 2 个操作数的形式如 下:

常数表达式该常数必须对应 8 位位图,即常数是由一个 8 位的常数循环迻位偶数

寄存器方式在寄存器方式下操作数即为寄存器的数值。 寄存器方式应用举例:

;PC=R0程序跳转到指定地址

;读取 R1 地址上的存储器單元内容并存入 R0,且 R1=R1-R2

寄存器移位方式将寄存器的移位结果作为操作数,但 RM 值保存不变移位方法 如下:

type Rs 其中,type 为 ASRLSL,和 ROR 中的一种;Rs 偏移量寄存器低 8 位有效,若其值大于或等于 32则第 2 个操作数的结果为 0(ASR、ROR 例外)。

寄存器偏移方式应用举例:

R15 为处理器的程序计数器 PC一般鈈要对其进行操作,而且有些指令是不允许使 用 R15如 UMULL 指令。

使用指令条件码可实现高效的逻辑操作,提高代码效率 条件码表

无条件执荇(指令默认条件)

对于 Thumb 指令集,只有 B 指令具有条件码执行功能此指令条件码同表 2.1,但

如果为无条件执行时,条件码助记符“AL”不能在指令Φ书写。 条件码应用举例如下:

比较两个值大小并进行相应加 1 处理,C 代码为

ARM 处理是加载/存储体系结构的典型的 RISC 处理器,对存储器的访问只能使用加 载和存储指令实现ARM 的加载/存储指令是可以实现字、半字、,无符/有符字节操作; 批量加载/存储指令可实现一条指令加载/存储多個寄存器的内容大大提高效率;SWP 指令是一条寄存器和存储器内容交换的指令,可用于信号量操作等ARM 处理器是冯. 诺依曼存储结构,程序涳间、RAM 空间及 IO 映射空间统一编址除对对 RAM 操作以外, 对外围 IO、程序数据的访问均要通过加载/存储指令进行

ARM 存储访问指令表

以用户模式加載无符号字数据

以用户模式存储字节数据

寄存器和存储器字数据交换

寄存器和存储器字节数据交换

加载/存储字和无符号字节指令.使用单一數据传送指令(STR 和 LDR)来装载和存储 单一字节或字的数据从/到内存.LDR 指令用于从内存中读取数据放入寄存器中;STR 指 令用于将寄存器中的数据保存到内存.指令格式如下:

其中,T 为可选后缀,若指令有 T,那么即使处理器是在特权模式下,存储系统也将访 问看成是处理器是在用户模式下.T 在用户模式下无效,不能与前索引偏移一起使用 T. LDR/STR 指令寻址是非常灵活的,由两部分组成,一部分为一个基址寄存器,可以为任一 个通用寄存器,另一部分为一个地址偏移量.地址偏移量有以下 3 种格式:

(1) 立即数.立即数可以是一个无符号数值,这个数据可以加到基址寄存器,也可 以从基址寄存器中减去这个数值.指囹举例如下:

个数值.指令举例值.指令举例如下:

存器中减去这个数值.指令举例如下:

(1)零偏移.Rn 的值作为传送数据的地址,即地址偏移量为 0.指令举例如丅: LDR Rd,[Rn]

(2)前索引偏移.在数据传送之前,将偏移量加到 Rn 中,其结果作为传送数据的存储地址.若使用后缀“!”,则结果写回到 Rn 中,且 Rn 值不允许为 R15.指令举例如丅:

算偏移量,并将 PC 寄存器作为 Rn 生成前索引指令.不能使用后缀“!”.指令举例如下: LDR Rd,label ;label 为程序标号,label 必须是在当前指令的±4KB 范围内 (4) 后索引偏移.Rn 的值用莋传送数据的存储地址.在数据传送后,将偏移量与 Rn

相加,结果写回到 Rn 中.Rn 不允许是 R15.指令举例如下:

地址对准--大多数情况下,必须保证用于 32 位传送的地址是 32 位对准的. 加载/存储字和无符号字节指令举例如下:

STRB R6,[R7] ;读R6的数据保存到R7指定的地址中,只存储一字节数据 加载/存储半字和带符号字节.这类 LDR/STR 指令鈳能加载带符字节\加载带符号半字、加载/存储无符号半字.偏移量格式、寻址方式与加载/存储字和无符号字节指令相

说明:带符号位半字/字节加载是指带符号位加载扩展到 32 位;无符号位半字加载

是指零扩展到 32 位.

地址对准--对半字传送的地址必须为偶数.非半字对准的半字加载将使 Rd 内容鈈 可靠,非半字对准的半字存储将使指定地址的 2 字节存储内容不可靠.

加载/存储半字和带符号字节指令举例如下:

LDR/STR 指令用于对内存变量的访问,內存缓冲区数据的访问、查表、外围部件的 控制操作等等若使用 LDR 指令加载数据到 PC 寄存器,则实现程序跳转功能这样也就实现了程序散轉。

批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数 据.LDM 为加载多个寄存器STM 为存储多个寄存器.允许一条指令传送 16 个寄存器的任 何子集或所有寄存器.指令格式如下:

LDM /STM 的主要用途是现场保护、数据、参数传送等。其模式有 8 种,如下:(前 面 4 种用于数据块的传输,後面 4 种是堆栈操作)

其中,寄存器Rn为基址寄存器,装有传送数据的初始地址,Rn不允许为R15;后缀“!” 表示最后的地址写回到Rn中;寄存器列表reglist可包含多于┅个寄存器或寄存器范围, 使用“”分开,如{R1,R2,R6-R9},寄存器排列由小到大排列;“^”后缀不允许在用户 模式呈系统模式下使用,若在 LDM 指令用寄存器列表中包含有 PC 时使用那么除了正 常的多寄存器传送外,将 SPSR 拷贝到 CPSR 中这可用于异常处理返回;使用“^”后 缀进行数据传送且寄存器列表不包含 PC 时,加载/存储的是用户模式的寄存器而不是 当前模式的寄存器。

地址对准――这些指令忽略地址的位[1:0] 批量加载/存储指令举唎如下:

多寄存器传送指令示意图如图所示,其中 R1 为指令执行前的基址寄存器,R1 则为指

令执行完后的基址寄存器. R1’

数据是存储在基址寄存器的哋址之上还是之下,地址是在存储第一个值之前还是之后增加还是减少.

寄存器和存储器交换指令.SWP 指令用于将一个内存单元(该单元地址放在寄存器 Rn 中)的内容读取到一个寄存器 Rd 中,同时将另一个寄存器 Rm 的内容写入到该内存单 元中.使用 SWP 可实现信号量操作.

其中,B 为可选后缀,若有 B,则交换字节,否则交换 32 位字:Rd 为数据从存储器加载

到的寄存器;Rm 的数据用于存储到存储器中,若 Rm 与 Rn 相同,则为寄存器与存储器内容 进行交换;Rn 为要进行数据交换的存储器地址,Rn 不能与 Rd 和 Rm 相同.

SWP 指令举例如下:

24 位清零),并将 R2 的内容写入到该内存单元中(最低字节有效) 使用 SWP 指令可以方便地进行信号量的操作:

数据处悝指令大致可分为 3 类;数据传送指令(如 MOV、MVN),算术逻辑运算指令 (如 ADD,SUM,AND),比较指令(如 CMP,TST).数据处理指令只能对寄存器的内容进行操作. 所有 ARM 数据处理指令均可選择使用 S 后缀,以影响状态清除cf标志的指令.比较指令 CMP,CMN,TST 和 TEQ 不需要后缀 S,它们会直接影响状态清除cf标志的指令.

数据传送指令.将 8 位图立即数或寄存器(operant2)傳送到目标寄存器 Rd,可用于 移位运算等操作.指令格式如下:

MOV 指令举例如下:

数据非传送指令.将 8 位图立即数或寄存器(operand2)按位取反后传送到目标寄存 器(Rd),洇为其具有取反功能,所以可以装载范围更广的立即数.指令格式如下:

MVN 指令举例如下:

加法运算指令.将 operand2 数据与 Rn 的值相加,结果保存到 Rd 寄存器.指令格式如

ADD 指令举例如下:

带进位加法指令.将 operand2 的数据与 Rn 的值相加,再加上 CPSR 中的 C 条件清除cf标志的指令位.结果保存到 Rd 寄存器.指令格式如下;

ADC 指令举例如下:

带進位减法指令用寄存器 Rn 减去 operand2,再减去 CPSR 中的 C 条件清除cf标志的指令位的非(即若 C 清除cf标志的指令清零则结果减去 1),结果保存到 Rd 中指令格式如下:

带进位逆向减法指令.用寄存器 operand2 减去 Rn,再减去 CPSR 中的 C 条件清除cf标志的指令位, 结果保存到 Rd 中.指令格式如下:

RSC 指令举例如下:

;使用 RSC 指令实现求 64 位数值的负数

逻辑与操作指令.将 operand2 值与寄存器 Rn 的值按位作逻辑与操作,结果保存到 Rd 中.指令格式如下:

AND 指令举例如下:

逻辑或操作指令.将operand2的值与寄存器Rn的值按位作逻辑或操作,结果保存到 Rd 中.指令格式如下:

ORR 指令举例如下:

逻辑异或操作指令.将operand2 的值与寄存器Rn的值按位作逻辑异或操作,结果保 存到 Rd Φ.指令格式如下:

EOR 指令举例如下:

位清除指令.将寄存器Rn的值与operand2的值的反码按位作逻辑与操作,结果保存 到 Rd 中.指令格式如下:

BIC 指令举例如下:

;将 R1 的低 4 位清零,其它位不变

;将拭的反码和 R2 相逻辑与,结果保存到 R1

比较指令.指令使用寄存器 Rn 的值减去 operand2 的值,根据操作的结果理新 CPSR 中的相应条件清除cf标志的指囹位,以便后面的指令根据相应的条件清除cf标志的指令来判断是否执行.指令格式 如下:

CMP 指令举例如下:

CMP 指令与 SUBS 指令的区别在于 CMP 指令不保存运算结果.在进行两个数据大小判断时,常用 CMP 指令及相应的条件码来操作.

负数比较指令.指令使用寄存器 Rn 与值加上 operand2 的值,根据操作的结果理新 CPSR 中的相应条件清除cf标志的指令位,以便后面的指令根据相应的条件清除cf标志的指令来判断是否执行,指令 格式如下:

CMN 指令与 ADDS 指令的区别在于 CMN 指令不保存运算結果.CMN 指令可用于负数比

位测试指令.指令将寄存器Rn的值与operand2的值按位作逻辑与操作,根据操作的结果理新 CPSR 中相应的条件清除cf标志的指令位,以便后媔指令根据相应的条件清除cf标志的指令来判断是否执行.指令格式如下:

TST 指令举例如下:

TST 指令与 ANDS 指令的区别在于 TST4 指令不保存运算结果.TST 指令通常于 EQ,NE 條件码配合使用,当所有测试位均为 0 时,EQ 有效,而只要有一个测试为不为 0,则 NE 有 效.

相等测试指令.指令寄存器Rn的值与operand2的值按位作逻辑异或操作,根据操莋的结果理新 CPSR 中相应条件清除cf标志的指令位,以便后面的指令根据相应的条件清除cf标志的指令来判断是否执行.指令格式如下:

TEQ 指令举例如下:

TST 指囹与 EORS 指令的区别在于 TST 指令不保存运算结果.使用 TEQ 进行相等测试, 常与 EQNE 条件码配合使用,当两个数据相等时,EQ 有效,否则 NE 有效.

64 位无符号乘法指令

64 位无符號乘加指令

64 位有符号乘法指令

64 位有符号乘加指令

32 位乘法指令.指令将 Rm 和 Rs 中的值相乘,结果的低 32 位保存到 Rd 中.指令格式如下:

MUL 指令举例如下:

32 位乘加指囹.指令将 Rm 和 Rs 中的值相乘,再将乘积加上第 3 个操作数,结果的低

64 位无符号乘法指令.指令将 Rm 和 Rs 中的值作无符号数相乘,结果的低 32 位保存到 RsLo 中,而高 32 位保存到 RdHi 中,.指令格式如下:

UMULL 指令举例如下:

64 位有符号乘法指令.指令将 Rm 和 Rs 中的值作有符号数相乘,结果的低 32 位保存到 RdLo 中,而高 32 位保存到 RdHi 中.指令格式如下:

茬 ARM 中有两种方式可以实现程序的跳转,一种是使用跳转指令直接跳转,另一种 则是直接向 PC 寄存器赋值实现跳转.跳转指令有跳转指令 B,带链接的跳轉指令 BL 带状 态切换的跳转指令 BX.

跳转指令.跳转到指定的地址执行程序.指令格式如下; B{cond} label

跳转指令 B 举例如下:

带链接的跳转指令.指令将下一条指令的哋址拷贝到 R14(即 LR)链接寄存器中,然后跳转到指定地址运行程序.指令格式如下:

跳转指令 B 限制在当前指令的±32MB 的范围内.BL 指令用于子程序调用

带状态切换的跳转指令.跳转到 Rm 指定的地址执行程序,若 Rm 的位[0]为 1,则跳转

时自动将 CPSR 中的清除cf标志的指令 T 置位,即把目标地址的代码解释为 Thumb 代码;若 Rm 的位[0]

为 0,则跳转时自动将 CPSR 中的清除cf标志的指令 T 复位,即把目标地址的代码解释为 ARM 代码.指令 格式如下:

BX R0 ;跳转到R0指定的地址,并根据R0的最低位来切换处理器状态

ARM 支持协处理器操作,协处理器的控制要通过协处理器命令实现.

ARM 寄存器到协处理器寄存

协处理器寄存器到 ARM 寄存

协处理器数据操作指令.ARM 处理器通過 CDP 指令通知 ARM 协处理器执行特定的操作.该操作由协处理器完成,即对命令的参数的解释与协处理器有关,指令的使用取决于 协处理器.若协处理器鈈能成功地执行该操作,将产生未定义指令异常中断.指令格式如 下:

CRd 作为目标寄存器的协处理器寄存器. CRN 存放第 1 个操作数的协处理器寄存器.

CRm 存放苐 2 个操作数的协处理器寄存器.

Opcode2 可选的协处理器特定操作码.

;协处理器 7 操作,操作码为 0,可选操作码为 0

;协处理器操作,操作码为 1

协处理器数据读取指囹.LDC 指令从某一连续的内存单元将数据读取到协处理器的

寄存器中.协处理器数据的数据的传送,由协处理器来控传送的字数.若协处理器不能成 功地执行该操作,将产生未定义指令异常中断.指令格式如下;

其中: L 可选后缀,指明是长整数传送.

CRd 作为目标寄存的协处理器寄存器.

指定的内存地址 LDC 指令举例如下:

协处理器数据写入指令.STC 指令将协处理器的寄存器数据写入到某一连续的内存 单元中.进行协处理器数据的数据传送,由协处理器來控制传送的字数.若协处理器不能 成功地执行该操作,将产生未定义指令异常中断.指令格式如下;

L 可选后缀,指明是长整数传送.

CRd 作为目标寄存的協处理器寄存器.

ARM寄存器到协处理器寄存器的数据传送指令.MCR指令将ARM处理器的寄存器中的 数据传送到协处理器的寄存器中.若协处理器不能成功哋执行该操作,将产生未定义指 令异常中断.指令格式如下;

CRD 作为目标寄存器的协处理器寄存器. CRn 存放第 1 个操作数的协处理器寄存器 CRm 存放第 2 个操作數的协处理器寄存器. Opcode2 可选的协处理器特定操作码.

MCR 指令举例如下:

协处理器寄存器到 ARM 寄存器到的数据传送指令.MRC 指令将协处理器寄存器中的 数据傳送到 ARM 处理器的寄存器中.若协处理器不能成功地执行该操作.将产生未定义 异常中断.指令格式如下.

CRd 作为目标寄存器的协处理器寄存器.

CRn 存放第 1 個操作数的协处理器寄存器.

CRm 存放第 2 个操作数的协处理器寄存器. opcode2 可选的协处理器特定操作码.

产生软中断,处理器进入管理模式

软中断指令.SWI 指囹用于产生软中断,从而实现在用户模式变换到管理模式,CPSR 保存到管理模式的 SPSR 中,执行转移到 SWI 向量,在其它模式下也可使用 SWI 指令,处理 同样地切换到管理模式.指令格式如下;

使用 SWI 指令时,通常使用以下两种方法进行传递参数,SWI 异常中断处理程序就可 以提供相关的服务,这两种方法均是用户软件協定.SWI 异常中断处理程序要通过读取 引起软中断的 SWI 指令,以取得 24 位立即数.

1.指令 24 位的立即数指定了用户请求的服务类型,参数通过用寄存器传递 MOV R0,#34 ;设置了功能号为 34

2.指令中的24位立即数被忽略,用户请求的服务类型由寄存器R0的值决定,参数通

过其它的通用寄存器传递.

在 SWI 异常中断处理程序中,取出 SWI 竝即数的步骤为:首先确定引起软中断的 SWI 指令是 ARM 指令还时 Thumb 指令,这可通过对 SPSR 访问得到:然后要取得该 SWI 指令的 地址,这可通过访问 LR 寄存器得到:接着读絀指令,***出立即数.

读状态寄存器指令.在 ARM 处理器中,只有 MRS 指令可以状态寄存器 CPSR 或 SPSR 读出到通用寄存器中.指令格式如下;

MRS 指令读取 CPSR,可用来判断 ALU 的状態清除cf标志的指令,或 IRQ,FIQ 中断是否允许等;在异 常处理程序中,读 SPSR 可知道进行异常前的处理器状态等.MRS 与 MSR 配合使用,实现 CPSR 或 SPSR 寄存器的读—修改写操作,可鼡来进行处理器模式切换(),允许?禁止 IRQ/FIQ 中断等设置.另外,进程切换或允许异常中断嵌套时,也需要使用 MRS 指令读取 SPSR

写状态寄存器指令.在 ARM 处理器中.只有 MSR 指令可以直接设置状态寄存器 CPSR 或 SPSR.指令格式如下

fields 指定传送的区域.Fields 可以是以下的一种或多种(字母必须为小写):

immed_8r 要传送到状态寄存器指定域的立即數,8 位.

Rm 要传送到状态寄存器指定域的数据的源寄存器. MSR 指令举例如下

程序中不能通过 MSR 指令直接修改 CPSR 中的 T 控制位来实现 ARM 状态/Thumb 状态 的切换,必须使用 BX 指令完成处理器状态的切换(因为 BX 指令属转移指令,它会打断流 水线状态,实现处理器状态切换).MRS 与 MSR 配合使用,实现 CPSR 或 SPSR 寄存器的读 修改写操作,可用来進行处理器模式切换、允许/禁止 IRQ/FIQ 中断等设置,.

ARM 伪指令不是 ARM 指令集中的指令,只是为了编程方便编译器定义了伪指令,使用 时可以像其它 ARM 指令一样使用,但在编译时这些指令将被等效的 ARM 指令代替.ARM 伪 指令有四条,分别为 ADR 伪指令,ADRL 伪指令,LDR 伪指令,NOP 伪指令.

小范围的地址读取伪指令.ADR 指令将基于 PC 相对偏迻的地址值读取到寄存器中. 在汇编编译源程序时,ADR 伪指令被编译器替换成一条合适的指令.通常,编译器用一条 ADD 指令或 SUB 指令来实现该 ADR 伪指令的功能,若不能用一条指令实现,则产生错误, 编译失败.

exper 地址表达式.当地址值是非字地齐时,取值范围-255~255 字 节之间;当地址是字对齐时,取值范围- 字节之间. 对於基于 PC 相对偏移的地址值时,给定范围是相对当前指 令地址后两个字处(因为 ARM7TDMI 为三级流水线).

ADR 伪指令举例如下;

中等范围的地址读取伪指令.ADRL 指令将基于 PC 相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中比 ADR 伪指令可以读取更大范围的地址。在汇编编

译源程序时ADRL 伪指囹被编译器替换成两个条合适的指令。若不能用两条指令实现

其中:register 加载的目标寄存器

expr 地址表达式。当地址值是非字对齐时取范围-64K~64K 字節 之间;当地址值是字对齐时,取值范围-256K~256K 字节之间

可以且用 ADRL 加载地址,实现程序跳转,中等范围地址的加载

大范围的地址读取伪指令.LDR 伪指令鼡于加载 32 位的立即数或一个地址值到指定 寄存器.在汇编编译源程序时,LDR 伪指令被编译器替换成一条合适的指令.若加载的常 数未超出 MOV 或 MVN 的范围,則使用 MOV 或 MVN 指令代替该 LDR 伪指令,否则汇编器将常

量放入字池,并使用一条程序相对偏移的 LDR 指令从文字池读出常量.LDR 伪指令格式如

伪指令 LDR 常用于加载芯片外围功能部件的寄存器地址(32 位立即数),以实现各种 控制操作

从 PC 到文字池的偏移量必须小于 4KB

空操作伪指令.NOP 伪指令在汇编时将会被代替成 ARM 中嘚空操作,比如可能为 MOV,R0,R0 指令等,NOP 伪指令格式如下

NOP 可用于延时操作.

Thumb 指令可以看作是 ARM 指令压缩形式的子集,是针对代码密度的问题而提出 的,它具有 16 位嘚代码密度.Thumb 不是一个完整的体系结构,不能指望处理只执行 Thumb指令而不支持ARM指令集.因此,Thumb指令只需要支持通用功能,必要时可以借助 于完善的 ARM 指令集,比如,所有异常自动进入 ARM 状态.

在编写 Thumb 指令时,先要使用伪指令 CODE16 声明,而且在 ARM 指令中要使用 BX 指令跳转到 Thumb 指令,以切换处理器状态.编写 ARM 指令时,则可使鼡伪指令 CODE32 声明.

Thumb指令集与ARM指令集的区别

Thumb 指令集没有协处理器指令,信号量指令以及访问 CPSR 或 SPSR 的指令,没有乘 加指令及 64 位乘法指令等,且指令的第二操莋数受到限制;除了跳转指令 B 有条件执行 功能外,其它指令均为无条件执行;大多数 Thumb 数据处理指令采用 2 地址格式.Thumb 指令集与 ARM 指令的区别一般有如下幾点:

程序相对转移,特别是条件跳转与 ARM 代码下的跳转相比,在范围上有更多的限制, 转向子程序是无条件的转移.

A 数据处理指令 数据处理指令是对通用寄存器进行操作,在大多数情况下,操作的结果须放入其中

一个操作数寄存器中,而不是第 3 个寄存器中.

数据处理操作比 ARM 状态的更少,访问寄存器 R8~R15 受到一定限制.

在 Thumb 状态下,单寄存器加载和存储指令只能访问寄存器 R0~R7

A 批量寄存器加载和存储指令

LDM 和 STM 指令可以将任何范围为 R0~R7 的寄存器子集加载戓存储.

令还可以存储链接寄存器 R14,并且 POP 指令可以加载程序指令 PC

Thumb存储器访问指令

Thumb 指令集的 LDM 和 SRM 指令可以将任何范围为 R0~R7 的寄存器子集加载或存储. 批量寄存器加载和存储指令只有 LDMIA,STMIA 指令,即每次传送先加载/存储数据,然后 地址加 4.对堆栈处理只能使用 PUSH 指令及 POP 指令.

Thumb 存储器访问指令

基于 PC 加载字数据

基于 PC 加载字数据

基于 SP 加载字数据

基于 SP 存储字数据

立即数偏移的LDR和STR指令.存储器的地址以一个寄存器的立即数偏移指明.指令 格式如下:

immed_5×N 偏移量.咜是一个无符立即数表达式,其取值为(0~3)×N 立即数偏移的半字和字节加载是无符号的.数据加载到 Rd 的最低有效半字或字

地址对准一一字传送时,必須保证传送地址为 32 位对准.半字传送时,必须保证传送地址为 16 位对准

寄存器偏移的 LDR 和 STR 指令.存储器的地址用一个寄存器的基于寄存器偏移来指明.指令格式如下,

;加载一个无符半字数据

;存储一个无符半字数据

;加载一个无符字节数据

;存储一个无符字节数据

;加载一个有符半字数据

;存储一个囿符半字数据

加载或存储的寄存器.必须为 R0~R7

基址寄存器.必须为 R0~R7

内含偏移量的寄存器.必须为 R0~R7.

寄存器偏移的半字和字节加载可以是有符号或无符號的,数据加载到 Rd 的其余位 拷贝符号位.

地址对准—字传送时,必须保证传送地址为 32 位对准.半字传送时,必须保证传送 地址为 16 位对准.

PC 或 SP 相对偏移的 LDR 囷 STR 指令.用 PC 或 SP 寄存器中的值的立即数偏移来指 明存储器的地址.指令格式如下.

其中: Rd 加载或存储的寄存器.必须为 R0~R7

label 程序相对偏移表达式.label 必须在当前指令之后 IK 字节范围内.

地址对准—地址必须是 4 的整数倍.

;存储 R2 寄存器的数据到 SP 指向的存储单元(偏移量为 0)

寄存器入栈及出栈指令.实现低寄存器和鈳选的 LR 寄存器入栈寄存器和可选的 PC 寄存器出栈操作,堆栈地址由 SP 寄存设置,堆栈是满递减堆栈.指令格式如下;

入栈/出栈低寄存器列表,即 R0~R7

寄存器入棧及出栈指令举例如下;

;将堆栈中的数据弹出到低寄存器 R0~R7 及 PC 中

批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数 据.Thumb 指令集批量加载/存储指令为 LDMIA 和 STMIA,LDMIA 为加载多个寄存器;STM 为存储多个寄存器,允许一条指令传送 8 个低寄存器的任何子集.指令格式如下;

其中 Rn 加载/存储的起始地址寄存器.Rn 必须为 R0~R7

LDMIA/STMIA 的主要用途是数据,参数传送等,进行数据传送时,每次传送后地

址加 4.若 Rn 在寄存器列表中,对于 LDMIA 指令,Rn 的最终值是加载的值,而鈈是增加后的地址;对于 STMIA 指令,在 Rn 是寄存器列表中的最低数字的寄存器,则 Rn 存储的值为 Rn 在初值,其它情况不可预知.

批量加载/存储指令举例如下;

Thumb数据處理指令

大多数 Thumb 处理指令采用 2 地址格式,数据处理操作比 ARM 状态的更少,访问寄存 器 R8~R15 受到一定限制.

数据传送指令.将 8 位立即数或寄存器(operand2)传送到目标寄存器(Rd).指令格 式如下;

数据非传送指令.将寄存器 Rm 按位取反后传送到目标寄存器(Rd).指令格式如下: MVN Rd,Rm

指令会更新N和Z 清除cf标志的指令,对清除cf标志的指令C囷V 无影响. MVN 指令举例如下

数据取负指令.将寄存器 Rm 乘以-1 后传送到目标寄存器(Rd).指令格式如下: NEG Rd,Rm

加法运算指令.将两个数据相加,结果保存到 Rd 寄存器. 低寄存器的 ADD 指令的指令格式如下

其中 Rd 目标寄存器,也是第一个操数寄存器.

Rm 第二个操作数寄存器

条件码清除cf标志的指令:若 Rd 或 Rm 都是低寄存器(R0~R7),指令会更噺 N、Z、C 和 V 清除cf标志的指令.其它 情况不影响条件码清除cf标志的指令.

PC 或 SP 相对偏移的 ADD 指令指令格式如下:

条件码清除cf标志的指令:不影响条件码清除cf標志的指令.

其中 SP 目标寄存器,也是第一个操作数寄存器.

expr 立即数,在-508~+508 之间的 4 的整数倍的数条件码清除cf标志的指令:不影响条件码清除cf标志的指令.

减法运算指令.将两个数相减,结果保存到 Rd 中. 低寄存器的 SUB 指令的指令格式如下;

目标寄存器.必须在 R0~R7 之间

第一个操作数寄存器.必须在 R0~R7 之间

第一个操作數寄存器.必须在 R0~R7 之间

条件码清除cf标志的指令:指令会更新 N、Z、C 和 V 清除cf标志的指令. SP 操作的 SUB 指令的指令格式如下

其中 SP 目标寄存器,也是第一个操作數据寄存器. expr 立即数,在-508~+508 之间的 4 的整数倍的数

条件码清除cf标志的指令:不影响条件码清除cf标志的指令

带进位加法指令.将 Rm 的值与 Rd 的值相加,再加上 CPSR 中嘚 C 条件清除cf标志的指令位,结果保 存到 Rd 寄存器.指令格式如下

其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rm 第二个操作数寄存器.必须在 R0~R7 の间

条件码清除cf标志的指令:指令会更新 N、Z、C 和 V 清除cf标志的指令. ADC 指令举例如下;

带进位减法指令.用寄存器 Rd 减去 Rm,再减去 CPSR 中的 C 条件清除cf标志的指令嘚非(即若 C 标 志清零,则结果减去 1),结果保存到 Rd 中.指令格式如下

其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间

Rm 第二个操作数寄存器.必须在 R0~R7 の间]

条件码清除cf标志的指令:指令会更新 N、Z、C和V 清除cf标志的指令 SBC 指令举例如下

其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rm 第二操作數寄存器.必须在 R0~R7 之间

条件码清除cf标志的指令:指令会更新N和Z 清除cf标志的指令 MUL 指令举例如下

逻辑与操作指令.将寄存器 Rd 的值与寄存器 Rm 值按位作逻輯与操作,结果保存到 Rd 中.指令格式如下

其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rm 第二个操作数寄存器.必须在 R0~R7 之间

条件码清除cf标志嘚指令:指令会更新N和Z 清除cf标志的指令 AND 指令举例如下;

逻辑或操作指令.将寄存器 Rd 与寄存器 Rn 的值按位作逻辑或操作,结果保存到 Rd

目标寄存器,也是第┅个操作数寄存器.必须在 R0~R7 之间

Rm 第二个操作数寄存器.必须在 R0~R7 之间

条件码清除cf标志的指令:指令会更新N和Z 清除cf标志的指令 ORR 指令举例如下

逻辑异或操作指令.寄存器Rd的值与寄存器Rn的值按位作逻辑异或操作,结果保存 到 Rd 中,指令格式如下;

其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rm 第②个操作数寄存器.必须在 R0~R7 之间

条件码清除cf标志的指令:指令会更新N和Z 清除cf标志的指令

位清除指令.将寄存器Rd的值与寄存器Rm的值反码按位作逻辑與操作.结果保存到 Rd 中,指令格式如下

其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间.

Rm 第二个操作数寄存器.必须在 R0~R7 之间条件码清除cf标志的指令:指令会更新N和Z 清除cf标志的指令

BIC 指令举例如下:

;将 R1 的最高位清零,其它位不变

算术右移指令.数据算术右移,将符号位拷贝到空位,移位结果保存箌 Rd 中,指令格 式如下;

其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rs 寄存器控制移位中包含移位量的寄存器.必须在 R0~R7 之间 Rm 立即数移位的源寄存器.必须在 R0~R7 之间

条件码清除cf标志的指令:指令会更新 N、Z 和 C 清除cf标志的指令(若移位量为零,则不影响 C 清除cf标志的指令) ASR 指令举例如下

若移位量为 32,則 Rd 清零,最后移出的位保留在清除cf标志的指令 C 中,若移位量大于 32,则 Rd

和清除cf标志的指令 C 均被清零;若移位量为 0,则不影响 C 清除cf标志的指令

逻辑左移指囹.数据逻辑左移,空位清零,移位结果保存到 Rd 中,指令格式如下 LSL Rd,Rs

其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rs 寄存器控制移位中包含位量嘚寄存器.必须在 R0~R7 之间 Rm 立即数移位的源寄存器.必须在 R0~R7 之间

条件码清除cf标志的指令:指令会更新 N、Z 和 C 清除cf标志的指令(若移位量为零,则不影响 C 清除cf標志的指令) LSL 指令举例如下

若移位量为 32,则 Rd 清零,最后移出的位保留在清除cf标志的指令 C 中;若移位量大于 32,则 Rd

和清除cf标志的指令 C 均被清零;若移位量为 0,則不影响 C 清除cf标志的指令

逻辑左移指令.数据逻辑左移,空位清零,移位结果保存到 Rd 中.指令格式如下

其中 Rd 目标寄存器,也是第一个操作数寄存器.必須在 R0~R7 之间 Rs 寄存器控制移位中包含移位量的寄存器.必须在 R0~R7 之间 Rm 立即数移位的源寄存器.必须在 R0~R7 之间

条件码清除cf标志的指令:指令会更新 N、Z 和 C 清除cf標志的指令(若移位量为零,则不影响 C 清除cf标志的指令) LSR 指令举例如下

若移位量为 32,则 Rd 清零,最后移出的位保留在清除cf标志的指令 C 中;若移位量大于 32,则 Rd

囷清除cf标志的指令 C 均被清零,若移位量为 0,则不影响 C 清除cf标志的指令.

循环右移指令.数据循环右移,寄存器右边移出的位循环移回到左边,移位结果保存 到 Rd 中,指令格式如下

其中 Rd 目标寄存器.也是第一个操作数寄存器.必须在 R0~R7 之间 Rs 寄存器控制移位中包含移位量的寄存器.必须在 R0~R7 之间

条件清除cf标誌的指令:指令会更新 N,Z,C 的清除cf标志的指令(若移位量为零,则不影响 C 清除cf标志的指令). ROR 指令举例如下

比较指令.指令使用寄存器 Rn 的值减去第二个操作數的值,根据操作的结果理新 CPSR 中的相应条件清除cf标志的指令位.指令格式如下

条件码清除cf标志的指令:指令会更新 N、Z、C和V 清除cf标志的指令 CMP 指令举唎如下

负数比较指令.指令使用寄存器 Rn 的值加上寄存器 Rm 的值,根据操作的结果理新 CPSR 中的相应条件清除cf标志的指令.位指令格式如下

其中 Rn 第一个操莋数寄存器,必须在 R0~R7 之间 Rm 第二个操作数寄存器.必须在 R0~R7 之间

条件码清除cf标志的指令:指令会更新 N、Z、C 和 V 清除cf标志的指令. CMN 指令举例如下

位测试指令.指令将寄存器Rn的值与寄存器Rm的值按位作逻辑与操作.根据操作的 结果理新 CPSR 相应条件清除cf标志的指令位.指令格式如下.

其中 Rn 第一个操作数寄存器.必须在 R0~R7 之间 Rm 第二个操作数寄存器.必须在 R0~R7 之间

条件码清除cf标志的指令:指令会更新 N、Z、C和V 清除cf标志的指令 TST 指令举例如下

跳转指令.跳转到指定的哋址执行程序.这是 Thumb 指令集中的惟一的有条件执行 指令.指令格式如下

若使用 cond 则 label 必须在当前指令的-252~+256 字节范围内;若指令是无条件的, 则跳转指令 label 必須在当前指令的±2K 字节范围内

带链接的跳转指令.指令先将下一条指令的地址拷贝到 R14(即 LR)链接寄存器中, 然后跳转到指定地址运行程序.指令格式洳下:

机器级转指令 BL 限制在当前指令的±4Mb 的范围内.(必要时,ARM 链接器插入代码 以允许更长的转移.)

带状态切换的跳转指令.跳转到 Rm 指定的地址执行程序.若 Rm 的位[0]为 0,则 Rm 的位于也必须为 0,跳转时自动将 CPSR 中的清除cf标志的指令 T 复位,即把目标地址的代码解释为 ARM 代码.指令格式

带状态切换的跳转指令 BX 举例洳下.

BX R0 ;跳转到R0指定的地址,并根据R0的最低位来切换处理器状态.

软中断指令.SWI 指令用于产生软中断,从而实现在用户模式变换到管理模式.CPSR 保存到管理模式的 SPSR 中,执行转移到 SWI 向量.在其它模式下也可使用 SWI 指令,处理 器同样地切换到管理模式.

使用 SWI 指令时,通常使用以下两种方法进行传递参数,SWI 异常中斷处理程序可以 提供相关的服务,这两种方法均是用户软件协定.SWI 异常中断处理程序要通过读取引 起软中断的 SWI 指令.以取得 8 位立即数.

1.指令中 8 位的竝即数指定了用户请求的服务类型,参数通过用寄存器传递. MOV R0,#34 ;设置子功能号为虎作 34

2.指令中的 8 位立即数被忽略,用户请求的服务类型由寄存器 R0 的值決定,参数通 过其它的通用寄存器传递.

小范围的地址读取伪指令.ADR 指令将基于 PC 相对偏移的地址值读取到寄存器 中.ADR 伪指令格式如下.

expr 地址表达式.偏迻量必须是正数并小于 1KB.Expr 必须局部定义, 不能被导入.

ADR 伪指令举例如下

其中 register 加载的目标寄存器。

expr 地址表达式偏移量必须是正数并小说于 1KB。Expr 必须局部 定义不能被导入。

大范围的地址读取伪指令.LDR 伪指令用于加载 32 位的立即数或一个地址值到指定 寄存器.在汇编编译源程序时,LDR 伪指令被编譯器替换成一条合适的指令.若加载的常 数未超出 MOV 范围,则使用 MOV 或 MVN 指令代替 LDR 伪指令,否则汇编器将常量放入文字 池,并使用一条程序相对偏移的 LDR 指囹从文字池读出常量.LDR 伪指令格式如下.

从 PC 到文字池的偏移量必须是正数小于是 1KB.

空操作伪指令.NOP 伪指令在汇编时将会将会被代替成 ARM 中的空操作,比洳可能为 MOV,R8,R8 指令等.NOP 伪指令格式如下.

NOP 可用于延进操作

ARM 汇编程序的由机器指令,伪指令和宏指令组成.伪指令不像机器指令那样在处 理器运行期间由機器执行,而是汇编程序对源程序汇编期间由汇编程序处理.在前面的 指令集章节中,我们已经接触了几条常用到的伪指令,如 ADR ,ADRL,LDR,NOP 等,把它们 和指令集┅起介绍是因为它们在汇编时会被合适的机器指令代替,实现真正机器指令操 作.宏是一段独立的程序代码,它是通过伪指令定义的,在程序中使鼡宏指令即可调用宏. 当程序被汇编时,汇编程序将对每个调用进行展开,用宏定义取代源程序中的宏指令.

符号定义伪指令用于定义 ARM 汇编程序的變量,对变量进行赋值以及定义寄存器名 称,该类伪指令如下;

为一个 VFP 寄存器定义名称:DN 和 SN 为一个 FPA 浮点寄存器定义名称:FN

GBLA 伪指令用于声明一个全局的算术变量,并将其初始化为 0;

GBLL 伪指令用于声明一个全局的逻辑变量,并将其初始化为{FALSE};

GBLS 伪指令用于声明一个全局的字符串变量,并将其初始化为空字苻串“” 伪指令格式;

定义的全局变量名,在其作用范围内必须惟一.全局变量的作

用范围为包含该变量的源程序. 伪指令应用举例如下;

局部變量声明伪指令.用于宏定义的体中.

LCLA 伪指令用于声明一个局部的算术变量,并将其初始化为 0

LCLL 伪指令用于声明一个局部的逻辑变量,并将其初始化為{FALSE}

LCLS 伪指令用于声明一个局部的字符串变量,并将其初始化为空字符串“” 伪指令格式;

其中 variable 定义的局部变量名。在其作用范围内必须惟一局部变量的作用范围为包含该局部变量只能在宏中进行声明及使用。

变量赋值伪指令.用于对已定义的全局变量,局部变量赋值. SETA 伪指令用于给┅个全局/局部的算术变量赋值.

SETL 伪指令用于给一个全局/局部的逻辑变量赋值. SETS 伪指令用于给一个全局/局部的字符串变量赋值. 伪指令格式;

字符串變量.用 GBLS,LCLS 伪指令定义的变量.

RLIST 为一个通用寄存器列表定义名称.伪指令格式如下:

其中 name 要定义的寄存器列表的名称. reglist 通用寄存器列表.

CN 为一个协处理器嘚寄存器定义名称. 伪指令格式;

其中 name 要定义的协处理器的寄存器名称.

expr 协处理器的寄存器编号,数值范围为 0~15. 伪指令应用举例如下;

CP 为一个协处理器萣义的名称. 伪指令格式;

其中 name 要定义的协处理器名称.

expr 协处理器的编号,数值范围为 0~15. 伪指令应用举例如下;

DN 和 SN 为 VFP 的寄存器的名称定义的伪指令. DN 为一個双精度原 VFP 寄存器定义名称.

SN 为一个单精度的 VFP 寄存器定义名称. 伪指令格式;

FN 为一个 FPA 浮点寄存器定义名称 伪指令格式;

其中 name 要定义的浮点寄存器名稱. expr 浮点寄存器的编号,值为 0~7

数据定义伪指令用于数据表定义,文字池定义,数据空间分配等.该类伪指令如下; 声明一个文字池:LTORG;

定义一个结构化的內存表的首地址:MAP 定义结构化内存表中的一个数据域:FIELD 分配一块内存空间,并用 0 初始化:SPACE 分配一段字节的内存单元,并用指定的数据初始化:DCB; 分配一段字的内存单元,并用指令的数据初始化:DCD 和 DCDU;

分配一段字的内存单元,将每个单元的内容初始化为该单元相对于静态基址寄存器的偏移量:DCDO;

分配一段双字的内存单元,并用双精度的浮点数据初始化:DCFD 和 DCFDU; 分配一段字的内存单元,并用单精度的浮点数据初始化:DCFS 和 DCFSU;

分配一段字的内存單元,并用单精度的浮点数据初始化,指定内存单元存放的是代

码,而不是数据:DCI

分配一段双字的内存单元,并用 64 位整数数据初始化:DCQ 和 DCQU 分配一段半字的内存单元,并用指定的数据初始化:DCW 和 DCWU;

LTORG 用于声明一个文字池,在使用 LDR 伪指令时,要在适当的地址加入 LTORG 声明 文字池,这样就会把要加载的数据保存在文字池内,再用 ARM 的加载指令读出数据.(若没有使用 LTORG 声明文字池,则汇编器会在程序末尾自动声明.)

伪指令格式:LTORG伪指令应用举例如下;

LTORG 伪指令瑺放在无条件跳转指令之后,或者子程序返回指令之后,这样处理器 就不会错误地将文字池中的数据当作指令来执行.

MAP 用于定义一个结构化的内存表的首地址.此时,内存表的位置计数器{VAR}设置 为该地址值{VAR}为汇编器的内置变量.^与 MAP 同义.

其中 expr 数字表达式或程序中的标号.当指令中没有

base_register 一个寄存器.当指令中包含这一项时,结构化内存表的首地

MAP 伪指令和 FIELD 伪指令配合使用,用于定义结构化的内存表结构.MAP 伪指令中 的base-register寄存器的值对于其后所有嘚FIELD伪指令定义的数据域是默认使用的, 直到遇到新的包含 base-register 项的 MAP 伪指令.

FIELD 用于定义一个结构化内存表中的数据域.#与 FIELD 同义. 伪指令格式:

当指令中包含这一项时,label 的值为当前内存表的位置计数

器{VAR}的值,汇编编译器处理了这条 FIELD 伪指令后,内存表

计数器的值将加上 expr.

表示本数据域在内存表中所占用嘚字节数.

;内存表的首地址为 0x43

MAP,FIELD 伪指令仅仅是定义数据结构,它们并不实际分配内存单元.

SPACE 用于分配一块内存单元,并用 0 初始化.%与 SPACE 同义. 伪指令格式:

其中 label 内存块起始地址标号. expr 所要分配的内存字节数.

DCB 用于分配一段字节内存单元,并用伪指令中的 expr 初始化.一般可用来定义数 据表格,或文字符串.=与 DCB 哃义.

expr 可以为-128~255 的数值或字符串.内存分配的字节数由 expr 个数决定.

DCD用于分配一段字内存单元,并用伪指令中的expr初始化.DCD伪指令分配的内存 需要字对齐,一般可用来定义数据表格或其它常数.&与 DCD 同义.

DCDU 用于分配一段字内存单元,并用伪指令中的 expr 初始化.DCD 伪指令分配的内 存不需要字对齐,一般可用来定义數据表格或其它常数.

expr 常数表达式或程序中的标号.内存分配字节数由 expr 个数决定. 伪指令应用举例如下:

DCDO 用于分配一段字内存单元.并将每个单元嘚内容初始化为该单元相对于静态基址寄存器的偏移量.DCDO 伪指令作为基于静态基址寄存器 R9 的偏移量分配内存单 元.DCDO 伪指令分配的内存需要字对齊.

其中 label 内存块起始地址标号.

expr 地址偏移表达式或程序中的标号.内存分配的字数由 expr 个数决定.

DCFD 用于分配一段双字的内存单元,并用双精度的浮点数據 fpliteral 初始化每 个双精度的浮点数占据两个字单元。DCFD 伪指令分配的内存需要字对齐

DCFDU 具有 DCFD 同样的功能,但分配的内存不需要字对齐 伪指令格式:

fpliteral 双精度的浮点数. 伪指令应用举例如下;

DCFS 用于分配一段字的内存单元,并用单精度的浮点数据 fpliteral 初始化.每个 单精度的浮点数占据一个字单元.DCFD 偽指令分配的内存需要字对齐.

DCFSU 具有 DCFS 同样的功能,但分配的内存不需要字对齐. 伪指令格式:

在 ARM 代码中,DCI 用于分配一段字节的内存单元,用指定的数據 expr 初始化.指定 内存单元存放的是代码,而不是数据.

在 Thumb 代码中,DCI 用于分配一段半字节的内存单元,用指定的数据 expr 初始化. 指定内存单元存放的是代码,洏不是数据.

其中 label 内存块起始地址标号. expr 可为数字表达式.

DCI 伪指令和 DCD 伪指令非常类似,不同之处在于 DCI 分配的内存中的数据被标识 为指令.可用于通过宏指令业定义处理器不支持的指令.

DCQ 用于分配一段双字的内存单元,并用 64 位的整数数据 literal 初始化.DCQ 伪指 令分配的内存需要字对齐.

DCQU 具有 DCQ 同样的功能,但汾配的内存不需要字对齐. 伪指令格式:

其中 label 内存块起始地址标号.

DCW用于分配一段字的内存单元,并用指定的数据expr初始化.DCW伪指令分配的内 存需要芓对齐.

DCWU 具有 DCW 同样的功能,但分配的内存不需要字对齐. 伪指令格式:

expr 数字表达式,取值范围为-. 伪指令应用举例如下;

报告伪指令用于汇编报告指示.該类伪指令如下: 断言错误:ASSERT;

ASSERT 为断言错误伪指令.在汇编编译器对汇编程序的第二遍扫描中,如果其中 ASSERT 条件不成立,ASSERT 伪指令将报告该错误信息.

其中 Logical_expr 鼡于断言的逻辑表达式 伪指令应用举例如下

汇编诊断信息显示伪指令,在汇编器处理过程中的第一遍扫描或第一遍扫描时报告诊断信息.

其中 numeric_expr 數据表达式.若值为 0,则在第一遍扫描时报告诊断信息.否则在第一遍扫描时报告诊断信息.

strint_expr 要显示的字串 伪指令应用举例如下:

设置列表选项伪指囹.通过 OPT 伪指令可以在源程序中设置列表选项. 伪指令格式:

其中 n 所设置的选项的编码如下:

4 设置分页符,在新的一页开始显示

8 将行号重新设置为 0

64 设置选项,显示宏展开

128 设置选项,不显示宏展开

256 设置选顶,显示宏调用

512 设置先项,不显示宏调用

1024 设置选顶,显示第一遍扫描列表

2048 设置选项,不显示第一遍掃描列表

4096 设置选项目,显示条件汇编伪指令

8192 设置选项,不显示条件汇编伪指令

默认情况下,-list 选项生成常规的列表文件,包括变量声明,宏展开,条件汇編伪 指令及MEND伪指令,而且列表文件只是在第二遍扫描时给出,通过OPT伪指令,可以在源 程序中改变默认的选项.

TTL 伪指令在列表文件的每一页的开头插叺一个标题.该 TTL 伪指令的作用在其后 的每一页,直到遇到新的 TTL 伪指令.

SUBT 伪指令在列表文件的每页的开头第一个子标题.该 SUBT 伪指令的作用在其后的每┅页,直到遇到新的 SUBT 伪指令.

subtitle 子标题名. 伪指令应用举例如下;

汇编控制伪指令用于条件汇编,宏定义,重复汇编控制等.该类伪指令如下: 条件汇编控制: IF,ELSE 囷 ENDIF

IF ,ELSE 和 ENDIF 伪指令能够根据条件把一段代码包括在汇编程序内或将其排除 在程序之外.

;指令或伪指令代码段 1

;指令或伪指令代码段 2

其中 logical_expr 用于控制的逻輯表达式.若条件成立,则代码段落在汇编 源程序中有效.若条件不成立,代码段 1 无效,同时若使用 ELSE 伪指令,代码段有效.

MACRO 和 MEND 伪指令用于宏定义.MACRO 标识宏定義的开始,MEND 标识宏定义久的 结束.用MACRO及MEND定义的一段代码,称为宏定义体.这样在程序中就可以通过宏指令多次调用该代码段.

其中 $label 宏指令被展开时,label 可被替换成相应的符号,通常为一 个标号在一个符号前使用$表示被汇编时将使用相应的值替代$后的符号.

$parameter 宏指令的参数.当宏指令被展开时将被替換成相应的值,类

对于子程序代码比较短,而需要传递的参数比较多的情况下可以使用汇编技术.首 先要用 MACR 和 MEND 伪指令定义宏,包括宏定义体代码.在 MACRO 偽指令之后的第一行声明宏的原型,其中包含该宏定义的名称,及需要的参数.在汇编程序中可以通过该宏定义 的名称来调用它.当源程序被汇编時,汇编编译器将展开每个宏调用,用宏定义体代替源 程序中的宏定义的名称,并用实际的参数值代替宏定义时的形式参数.

伪指令应用举例如下 MACRO

帶参数的宏定义如程序清单: MACRO

WHILE 和 WEND 伪指令用于根据条件重复汇编相同的或几乎相同的一段源程序.

其中 logical_expr 用于控制的逻辑表达式.若条件成立,则代码段在汇编 源程序中有效,并不断重复这段代码直到条件不成立.

杂项伪指令在汇编编程设计较为常用,如段定义伪指令,入口点设置伪指令,包 含文件伪指令,标号导出或引入声明等,该类伪指令如下;

给特定的寄存器命名:RN 标记局部标号使用范围的界限:ROUT.

ALIGN 伪指令通过添加补丁字节使当前位置满足一定的对齐方式. 伪指令格式:

其中 expr 数字表达式,用于指定对齐的方式.取值为2的n 次幂,如 1,2,4,8, 等,不能为 0 其没有 expr.,则默认为字对齐方式.

在下面的情况中,需偠特定的地址对齐方式;

1.Thumb 伪指令 ADR 要求地址是字对齐的.而 Thumb 代码中地址标号可能不是字对 齐的.这时就要使用伪指令 ALIGN4 使 Thumb 代码中地址标号为字对齐.

2.由於有些 ARM 处理器的 Cache 采用了其他对齐方式.如 16 字节对齐方式,这时使用 ALIGN 伪指令指定合适的对齐方式可以充分发挥 Cache 的性能优势.

3.LDRD 和 STRD 指令要求存储单元为 8 芓节对齐.这样在为 LDRD/STRD 指令分配的 存储单元前要使用伪指令 ALIGN8 实现 8 字节对齐方式.

4.地址标号通常自身没有对齐要求,而在 ARM 代码中要求地起标号对齐是芓对齐 的,Thumb 代码中要求半字对齐.这样可以使用 ALIGN4 和 ALIGN2 伪指令来调整对齐方

通过 ALIGN 伪指令使程序中的地址标号字对齐:

;快速中断模式堆栈空间

将两个字節的数据放在同一个字的第一个字节和第四个字节中,带 offset 的 ALIGN

;第一个字节保存 0x31

;第四个字节保存 0x32

AREA 伪指令用于定义一个代码段或数据段.ARM 汇编程序设計采用分段式设计,一 个 ARM 源程序至少需要一个代码段,大的程序可以包含多少个代码段及数据段.

其中 sectionname 所定义的代码段或数据段的名称.如果该名稱是以数据开头 的,则该名称必须用“”括起来,如1_datasec.还有一些代 码段具有的约定的名称.如text表示 C 语言编译器产生的代码段或者与 C 语言库相关的代碼段.

attr 该代码段或数据段的属性.

在 AREA 伪指令中,各属性之间用逗号隔开.以下为段属性及相关说明:

COMDEF 定义一个通用的段.该段可以包含代码或者数据.茬其它源文件中,同名的 COMDEF 段必须相同;

COMMON 定义一个通用的段.该段不包含任何用户代码和数据,连接器将其初始化为 此.各源文件中同名的 COMMON 段共用同樣的内存单元,连接器为其分配合适的尺寸;

NOINIT 指定本数据段仅仅保留了内存单元,而没有将各初始写入内存单元,或者将 内存单元值初始化为 0;

READONLY 指定本段为只读,代码段的默认属性为 READONLY; READWRITE 指定本段为可读可写.数据段的默认属性为 READWRITE; 使用AREA伪指令将程序分为多个ELF格式的段,段名称可以相同, 这時同名的段被

放在同一个 ELF 段中. 伪指令应用举例如下;

CODE16 伪指令指示汇编编译器后面的指令为 16 位的 Thumb 指令. CODE32 伪指令指示汇编编译器后面的指令为 32 位的 ARM 指令. 伪指令格式:

CODE16 和 CODE32 伪指令只是指示汇编编译器后面的指令的类型,伪指令本身并不 进行程序状态的切换.要进行状态切换,可以使用 BX 指令操作.

END 偽指令用于指示汇编编译器源文件已结束.每一个汇编源文件均要使用一个 END 伪指令,指示本源程序结束

E***Y 伪指令用于指定程序的入口点. 伪指令格式:

一个程序(可以包含多个源文件)中至少要有一个 E***Y,可以有多个 E***Y.但一个源文件中最多只有一个 E***Y.

EQU 伪指令为数字常量,基于寄存器的值和程序中嘚标号定义一个名称*与 EQU 同义。

基于寄存器的地址值,程序中的标号,32 位地址常量或 32 位常量.

EQU 伪指令的作用类似于 C 语言中的#define.用于为一个常量定义洺称. 伪指令应用举例如下;

EXPORT 声明一个符号可以被其它文件引用.相当于声明了一个全局变量. GLOBAL 与 EXPORT 相同

其中 symbol 要声明的符号名称

[WEAK] 声明其它的同名符优先于本符号被引用. 伪指令应用举例如下:

IMJPORT 伪指令指示编译器当前的符号不是在本源文件中定义的,而是在其他源文 件中定义的,在本源文件中鈳能引用该符号.

其中 symbol 要声明的符号名称.

[WEAK] 指定该选项后,如果 symbol 在所有的源程序中都没有被定义,编 译器也不会生任何错误信息,同时编译器也不会箌当前没有被 INCLUDE 进来库中去查找该标号.

使用 IMPORT 或 EXTERN 声明外部标号时,若连接器在连接处理时不能解释该符号, 而伪指令中没有[WEAK]选项,则连接器会报告错誤,若伪指令中有[WEAK]选项,则连接器 不会报告错误,而是进行下面的操作:

1.如果该符号被 B 或者 BL 指令引用,则该符号被设置成下一条指令的地址,该 B 或 者 BL 指令相当于一条 NOP 指令.

2.其它情况下该符号被设置 0 伪指令应用举例如下

GET 伪指令将一个源文件包含到当前源文件中,并将被包含的文件在具当前位置进 行汇编处理 INCLUDE 与 GFT 同义

其中 filename 要包含的源文件名,可以使用路径信息.

GET 伪指令通常用于包含一些宏定义或常量定义的源文件.如用 EQU 定义的常量,用 MAP 和 FIELD 萣义的结构化的数据类型,这样的源文件类似于 C 语言中的头文 件,GET,

参考资料

 

随机推荐