ArmV8常用汇编指令2

接上文,我们来分析一些具体指令。

1.加载存储指令

Load/Store可以分为立即数、寄存器等操作,格式如下:

这里Rn和Rt均为4位,原因在于,A32/T32是16个通用寄存器。因此使用4bit刚好可以遍历所有。如果是运行在AArch64,则需要5bit。

好,上述格式问题后续再讨论,先看下指令。

在该架构中,所有数据处理都需要在通用寄存器中完成,首先需要把待处理数据从内存加载到通用寄存器,处理后把结果写入内存。

常见内存加载指令:

|-------|----------------------|---|
| LDR | Word load | |
| LDRD | Dword load | |
| LDRB | Byte load | |
| LDRH | Halfword load | |
| LDRSB | Signed byte load | |
| LDRSH | Signed haflword load | |

常见存储指令:

|------|----------------|---|
| STR | Word store | |
| STRD | Dword store | |
| STRB | Byte store | |
| STRH | Halfword store | |

在使用load/store指令时,需要了解寻址的方式。具体如下:

|---------------|-------------------|------------------------------------------------------------------------|
| 寻址模式 | 举例 | |
| 基地址寻址 | LDR r0,[r1] | 将r1中的数据加载到r0 |
| 基地址+偏移寻址(前变基) | LDR r0,[r1,#8] | 将r1+8(必须是8的倍数)的内存数据加载到r0 |
| 后变基 | LDR r0,[r1],#8 | 将r1的值加载到r0,然后再加立即数8 |
| 基地址扩展 | LDR r0,[r1,r2] | R1的值+r2的值,加载到r0 |
| PC相对地址 | LDR rx, <label> | lable内存地址赋给rx,必须是PC附近的地址 LDR\LDRB\LDRSB\LDRH\LDRSH ±4095 LDRD ±255 |

LDR伪指令(大范围内加载地址),格式如下:

LDR Rt, =<label>

当该指令第二个参数为=时,表示伪指令,否则就是普通的内存访问指令。

例如

cpp 复制代码
data:

.long 0x1

LDR R1, = data

LDR R0, [R1]

首先将数据0x1加载到寄存器R1中(伪指令);

然后第二条LDR是普通内存访问指令,以R0寄存器的值作为内存地址,加载这个内存地址的值到R0,因此R0值为0x1。

多字节内存load/store指令

<LDM|STM> {<addressing_mode>}{<cond>} Rb{!}, <register list>

LDM r10,{r0, r1, r4}

2 数据处理指令

  • 运算

|-----|--------------------------------------------|------------------------------------------------------------|
| 指令 | 含义 | 举例 |
| ADD | 不进位加 | ADD r0, r1,r2 |
| ADC | 带进位加 | |
| SUB | 不进位减 | SUB r0, r1,r2 // r0 = r1-r2 注意如果要用立即数,只能用T32 SUB Rd, r1,#1 |
| SBC | 带进位减 | |
| RSB | 不进位的反减法 | RSB r0, r1,r2 // r0 = r2-r1 |
| RSC | 带进位的反减法 | |
| CMN | 负数比较,把寄存器和另一个寄存器或者立即数取反后进行比较,更新CPSR条件标志位的值 | CMN r1,#100 //r1的值和100相加,根据结果设置CPSR标志位 |
| CMP | 比较 | CMP r1, #100 //r1-100,根据结构设置CPSR标志位,不存储结果 |
| AND | 逻辑与 | |
| BIC | 位清除:用Operand2中相应位的补码对Rn中的位执行与运算 | BIC Rd, Rn,Oprand2 |
| EOR | 逻辑或 | |
| TST | 用Operand2测试Rn(按位与),不改变Rn,值更新标志位 | TST Rn, Operand2 |
| TEQ | 用Operand2测试Rn(按位异或),不改变Rn,值更新标志位 | TEQ Rn, Operand2 |
| MOV | Copy | MOV r0,r1 //copy r1 to r0 |

  • 移位、旋转

其中,ASR:算数右移,带符号的右移,符号bit位是[32];右移n位,左边被移走的n位用符号bit[31]进行填充

  • 乘除法
  • 位操作
  • 字节反转

3 控制流指令

  • 分支指令

B:跳转

BL:带返回地址(存放到R14)的跳转

BLX:带指令转换、返回地址的跳转 BLX Rn 当Rnbit0置1时,切到T32;置0,切到A32

  • CBZ/CBNZ

语法格式:CB(N)Z <Rn>, <label>

CBZ 如果Rn等于0,则跳转到label指向

CBNZ 如果Rn不等于0,跳转到label

注意,该指令只能branch 4到130byte

  • IT{T/E}{T/E}{T/E} <cond>
  • Supervisor Call(SVC)/Hypervisor Call(HVC)

语法:SVC #imm。SVC指令导致异常。这意味着处理器模式变为Supervisor,即CPSR保存为Supervisor模式SPSR,并执行分支到SVC向量。Imm被处理器忽略。但是,异常处理程序可以检索它,以确定正在请求什么服务

HVC #imm 处理器进入Hyp模式,CPSR值保存到Hyp模式SPSR,执行分支到HVC向量。

HVC不能处于IT块里

4 Misc指令

  • 协处理器指令

CDP 初始化一个协处理器数据处理操作

MRC 将协处理器的值移动到ARM寄存器

MCR 将ARM寄存器值移动到协处理器

LDC 从内存中加载到协处理器寄存器

STC 从协处理器存储到内存

  • PSR访问

使用MSR 从通用寄存器(或者立即数)传输数据给SPSR/CPSR;

使用MRS把CPSR/SPSR内容传递给通用寄存器,例如下面这段代码

MRS r0,CPSR // read CPSR into r0

BIC r0,r0,#0x80 //清除IRQ mask,使能IRQ

MSR CPSR_c, r0 //只修改CPSR_c这一个bit

SETEND 用于选择数据访问是大端还是小端(用于选择大小端混用系统)

  • BKPT\WFI\NOP等

BKPT Breakpoint,用于debug代理商

WFI wait for interrupt ,cpu切至standby、等待debug或者中断时间

NOP,没有操作

5 新的A32/T32指令

6 DSP

DSP指令都是single instruction multiple data

相关推荐
我在人间贩卖青春5 天前
汇编之伪指令
汇编·伪指令
我在人间贩卖青春6 天前
汇编之伪操作
汇编·伪操作
济6176 天前
FreeRTOS基础--堆栈概念与汇编指令实战解析
汇编·嵌入式·freertos
myloveasuka6 天前
汇编TEST指令
汇编
我在人间贩卖青春6 天前
汇编编程驱动LED
汇编·点亮led
我在人间贩卖青春6 天前
汇编和C编程相互调用
汇编·混合编程
myloveasuka7 天前
寻址方式笔记
汇编·笔记·计算机组成原理
请输入蚊子7 天前
《操作系统真象还原》 第六章 完善内核
linux·汇编·操作系统·bochs·操作系统真像还原
myloveasuka7 天前
指令格式举例
汇编·笔记·计算机组成原理
Stone.Wu7 天前
快速理解ARM Cortex-M流水线:指令执行过程通俗解释
arm