ARM汇编基础
2017-04-25 08:50
281 查看
ARM体系平台手册笔记05
并行加减指令
除了正常的数据处理和乘法指令之外,ARMv6还引入了一组并行加减指令 下面介绍6种基本的指令 ADD16 添加两个寄存器的顶部半字形成结果的上半部分。 添加相同两个寄存器的底部半字形成结果的底部半字部分 ADDSUBX 交换第二个操作数寄存器的半字,加上半字,减半字。 为啥这样设计,这里暂时不明白,后续章节有详细介绍 <opcode3>{<cond>} {S} <Rd> <Rn> <shifter_operand> 参照上面描述的指令格式,第二操作数实际上交换的shifter_operand SUBADDX 交换第二个操作数寄存器的半字,减去顶部半字,并增加底部半字 SUB16 从第二个操作数寄存器的上半部分减去第一个操作数寄存器的上半部分,形成结果的上半部分。 从第一个操作数寄存器的下半部分减去第二个操作数寄存器的下部半字,形成结果的下半部分。 ADD8 将第二个操作数寄存器的每个字节添加到第一个操作数寄存器的相应字节,以形成结果的相应字节 SUB8 将第一个操作数寄存器的相应字节中减去第二个操作数寄存器的每个字节,以形成结果的相应字节。 六种指令中的每一个可用于以下变体,即为这六种指令添加前缀: 有符号指示前缀: S 符号算术模2^8或2^16.设置CPSR GE位(请参见第A2-13页的GE [3:0]位)。 Q 有符号饱和算术 SH 有符号算术,将结果减半以避免溢出 无符号指示前缀: U 无符号运算模2^8或2^16.设置CPSR GE位(参见第A2-13页的GE [3:0]位) UQ 无符号饱和算术 UH 无符号算术,将结果减半以避免溢出 仅仅拿有符号前缀S Q SH举例:(后续章节由对这些指令用法有详细的文档说明) SADD16 SADDSUBX SUBADDX SSUB16 SADD8 SSUB8 QADD16 QADDSUBX QSUBADDX QSUB16 QADD8 QSUB8 SHADD16 SHADDSUBX SHSUBADDX SHSUB16 SHADD8 SHSUB8 后续章节指令有详细介绍
扩展指令
ARMv6及更高版本提供了几个指令,用于通过符号或零扩展字节到半字或字,以及将字的半字打包数据。 您可以选择将结果添加到另一个寄存器的内容。您可以在扩展之前将操作数寄存器的任意倍数旋转8位 下面介绍6种基本的指令: XTAB16 将一个寄存器的位[23:16]和位[7:0]扩展为16位,并将相应的半字添加到另一个寄存器中的值。 XTAB 将一个寄存器的位[7:0]扩展为32位,并将其添加到另一个寄存器中的值。 XTAH 将一个寄存器的位[15:0]扩展为32位,并将其添加到另一个寄存器中的值。 XTB16 将位[23:16]和位[7:0]分别扩展为16位 XTB 将扩展位[7:0]至32位 XTH 将位[15:0]扩展为32位 六种指令中的每一个可用于以下变体,即为这六种指令添加前缀: S 符号扩展,带或不带加法模 数2^16或2^32。 U 零(无符号)扩展名,带或不带加法模 数2^16或2^32 仅拿符号前缀U举例 UTXAB16 UTXAB UXTAH UXTB16 UXTB UXTH 后续章节有详细指令介绍
杂项算术指令
ARMv5及以上版本包括几个其他算术指令。 Count Leading zeros(CLZ)指令。 该指令在遇到第一个1位之前返回其操作数最高有效位的0个数(如果操作数为0,则返回32位)。 大白话,对寄存器直进行移位操作,直到最高位为1时停止移位,并记下移了多少次。 这两个典型的应用是: 1、要确定操作数应该向左移动多少位以使其正常化,以使其最高有效位为1(可用于整数除法程序) 2、要定位最高优先级位在哪一个掩码位(置)上 Unsigned sum of absolute differences(USAD)指令 ARMv6引入了无符号绝对差值(USAD8)指令和无符号绝对差值和累加(USADA8)指令 这些指令执行以下操作: 1.从两个寄存器取相应字节。 2.找出每对字节的无符号值之间的绝对差值。 3.求和四个绝对值。 4.可选地,将绝对差的和累积到第三寄存器中的值 其他杂项指令 PKHBT (Pack Halfword Bottom Top)将其第一个操作数的底部,最不重要的半字与其移位的第二个操作数的顶部(最重要)半字组合。偏移是从0到31的任意数量的左移。 PKHTB (Pack Halfword Top Bottom)将其第一个操作数的顶部,最重要的半字与其移位的第二个操作数的底部(最低有效)半字组合。这个变化是一个算术右移,任意数量从1到32 REV (Byte-Reverse Word)反转32位寄存器中的字节顺序 有意思的指令额^_^ REV16 (Byte-Reverse Packed Halfword)反转32位寄存器的每个16位半字的字节顺序。 REVSH(Byte-Reverse Signed Halfword) 反转32位寄存器的低16位半字的字节顺序,符号将结果扩展为32位。 SEL 根据GE标志的值,从其第一个操作数或其第二个操作数中选择其结果的每个字节。 SSAT(Signed Saturate) 将有符号的值饱和为有符号范围。您可以选择饱和发生的位位置。您可以在饱和发生之前对值进行移位。 USAT(Unsigned Saturate) 将有符号值饱和为无符号范围。您可以选择饱和发生的位位置。您可以在饱和发生之前对值进行移位 USAT16 将两个带符号的16位值饱和为无符号范围。您可以选择饱和发生的位位置 后续章节有详细指令介绍
CPSR访问指令
有两个指令用于将程序状态寄存器的内容移动到通用寄存器或从通用寄存器移出。可以访问CPSR和SPSR 此外,在ARMv6中,有几个指令可以直接写入CPSR中的特定位或位组。 每个状态寄存器传统上分为四个8位字段,可以单独写入: Bits[31:24] 标志字段 Bits[23:16] 状态字段 Bits[15:8] 扩展字段 Bits[7:0] 控制字段 CPSR value 改变CPSR的值有五个用途: •将条件代码标志(以及存在的Q标志)的值设置为已知值 •启用或禁用中断 •更改处理器模式(例如,初始化堆栈指针) •更改加载和存储操作的字节顺序 •更改处理器状态(J和T位) 注意: 只有通过BX,BLX或BXJ指令写入CPSR才能直接更改T和J位,并且在针对异常返回的指令中,将隐式SPSR转换为CPSR。 通过直接更改T或J位来尝试进入或离开Thumb或Jazelle状态将产生不可预测的后果。 例子: 这些示例假定ARM处理器已处于特权模式。如果ARM处理器以用户模式启动,只有标志更新有效果 MRS R0,CPSR ;读CPSR到R0寄存器 BIC R0,R0,#0XF0000000 ;清除 the N Z C and V 标志位(R0 = R0 & !0xF0000000) MSR CPSR_f,R0 ;更新CPSR状态寄存器的N Z C V标志位 MRS R0,CPSR ;read the cpsr ORR R0,R0,#0X80 ;set the interrupt disabled bit MSR CPSR_f,R0 ; Update the contrl bits in the cpsr //interrupt(IRQ) now diabbled MRS R0,CPSR BIC R0,R0,#0X1F ; r0 = r0 & !0x1f 清除模式位 ORR R0,R0,#0X11 ; R0 = R0 | 0x11 设置模式为FIQ模式 MSR CPSR_c,R0 ;更新CPSR状态寄存器控制模式位,进入FIQ模式 /> 状态寄存器访问指令列表 MRS 将PSR移动到通用寄存器 MSR 将通用寄存器移动到PSR寄存器 CPS 更改处理器状态。更改CPSR的一个或多个处理器模式和中断使能位,而不改变其他CPSR位。 SETEND 修改CPSR字节顺序E,位,而不改变CPSR中的任何其他位 处理器状态位也可以通过更新PC的各种分支(BX),加载和返回指令进行更新。 当它们用于Jazelle状态进入/退出和Thumb交互工作时,发生更改。
相关文章推荐
- #新闻拍一拍# IBM 招聘广告要求应聘者具备至少 12 年 K8S 使用经验
- vivi下重新调整分区
- ARM Linux系统启动
- Linux及ARM Linux程序开发笔记(零基础入门篇)
- 零基础入门篇之Linux及Arm-Linux程序开发笔记
- iOS逆向工程之Hopper中的ARM指令详解
- Mac下定时任务清理内存
- 我的 ARM+Linux 学习路线
- 64位Ubuntu 14.04上使用musleabi最小化交叉编译Android版PHP7
- 关于ARM启动的一篇文章
- ARM 的堆栈初始化详解
- ARM条件码与CPSR标志位的关系
- 加载/存储指令
- 关于ARM 汇编的一些疑问
- ARM汇编伪指令介绍
- linux的防火墙及arm与虚拟机共享
- 编译单个驱动的Makefile文件。
- ARM Linux设备树的应用例子1
- ARM Linux系统调用的原理
- Android LKM Rootkit,查找sys_call_table