当前位置:网站首页>ARM指令集之数据处理指令寻址方式
ARM指令集之数据处理指令寻址方式
2022-06-12 11:37:00 【fanxiaoyu321】
文章目录
所谓的寻址方式,是指当一个指令中的操作数涉及内存访问时,那么指令已什么样的方式来确定内存的地址。
ARM的寻址方式分好几类,这篇笔记记录了数据处理类指令的寻址方式。
数据处理指令
常见的数据处理指令如下表所示,它们支持相同的寻址方式。
| 助记符 | 说明 | 实现逻辑 |
|---|---|---|
| MOV | 数据传送 | Rd = Rn(Rn可能需要运算) |
| MVN | 数据取反传送 | Rd = ~Rn(Rn可能需要运算) |
| ADD | 加 | Rd = Rn + op2 |
| ADC | 带进位加 | Rd = Rn + op2 + C |
| AND | 逻辑加 | Rd = Rn && op2 |
| EOR | 逻辑异或 | Rd = Rn ^ op2 |
| SUB | 减 | Rd = Rn - op2 |
| SBC | 带进位的减 | Rd = Rn - op2 + C - 1 |
| RSB | 反转减 | Rd = op2 - Rn |
| RSC | 带进位的反转减 | Rd = op2 - Rn + C - 1 |
| TST | 测试 | Rn && op2的结果更新标志位 |
| TEQ | 测试相等 | Rn ^ op2的结果更新标志位 |
| CMP | 比较 | Rn - op2的结果更新标志位 |
| CMN | 符数比较 | Rn + op2的结果更新标志位 |
| ORR | 逻辑或 | Rd = Rn || op2 |
| BIC | 位清零 | Rd = Rn && ~(op2) |
寻址方式
ARM为数据处理指令支持11种寻址方式。
| 语法 | 说明 | |
|---|---|---|
| 1 | #<immediate> | 立即数寻址 |
| 2 | <Rm> | 寄存器寻址 |
| 3 | <Rm>, LSL #<shift_imm> | 寄存器逻辑左移立即数个位 |
| 4 | <Rm>, LSL <Rs> | 寄存器逻辑左移寄存器个位 |
| 5 | <Rm>, LSR #<shift_imm> | 寄存器逻辑右移立即数个位 |
| 6 | <Rm>, LSR <Rs> | 寄存器逻辑右移寄存器个位 |
| 7 | <Rm>, ASR #<shift_imm> | 寄存器算数右移立即数个位 |
| 8 | <Rm>, ASR <Rs> | 寄存器算数右移寄存器个位 |
| 9 | <Rm>, ROR #<shift_imm> | 寄存器循环右移立即数个位 |
| 10 | <Rm>, ROR <Rs> | 寄存器循环右移寄存器个位 |
| 11 | <Rm>, RRX | 寄存器扩展循环右移 |
- 逻辑移位指的是移位后,空余位用0补齐;
- 算数移位指的是移位后,空余位用原Rm[31]的值补齐;
- 循环移位不涉及补齐;
注:尽量避免用R15来用作上述寻址方式,因为流水线技术的原因,R15的值是当前指令的地址加8(3级流水线),这种变化不利于程序编写,此外某些情况下并不能使用R15。
1. 立即数寻址
立即数寻址时,每个立即数由一个8位的常数循环右移偶数位得到,其中循环右移的位数是由一个4bit数字*2表示。所以,并不是每一个32位的立即数都能通过这种方式指定,只有通过这种方式能够构造得到的立即数才是合法的。
立即数寻址的伪代码如下:
语法:#<immediate>
shifter_operand = immed_8 Rotate_Right (rotate_imm * 2)
if rotate_imm == 0 then
shifter_carry_out = C flag
else
shifter_carry_out = shifter_operand[31]
心得:首先,个人理解没有必要去研究到底一个立即数是否合法,编码时可以直接让汇编器帮忙检查;并且如果无法表示该立即数,我们可以通过ldr伪指令来将任意一个立即数传送到寄存器中,然后使用寄存器寻址方式来代替立即数寻址。
2. 寄存器寻址
语法: <Rm>
shifter_operand = Rm
shifter_carry_out = C flag
3. 寄存器逻辑左移立即数寻址
语法:<Rm>, LSL #<shift_imm>
if shift_imm == 0 then
shifter_operand = Rm
shifter_carray_out = C flag
else
shifter_operand = Rm Logical_Shift_Left shift_imm
shifter_carry_out = Rm[32 - shift_imm]
4. 寄存器逻辑左移寄存器寻址
语法:Rm>, LSL <Rs>
if Rs[7:0] == 0 then
shifter_operand = Rm
shifter_carray_out = C flag
elif Rs[7:0] < 32 then
shifter_operand = Rm Logical_Shift_Left Rs[7:0]
shifter_carry_out = Rm[32 - Rs[7:0]]
elif Rs[7:0] == 32 then
shifter_operand = 0
shifter_carry_out = Rm[0]
else
shifter_operand = 0
shifter_carry_out = 0
5. 寄存器逻辑右移立即数寻址
语法:<Rm>, LSR #<shift_imm>
if shift_imm == 0 then
shifter_operand = 0
shifter_carray_out = Rm[31]
else
shifter_operand = Rm Logical_Shift_Right shift_imm
shifter_carry_out = Rm[shift_imm - 1]
6. 寄存器逻辑右移寄存器寻址
语法:<Rm>, LSR <Rs>
if Rs[7:0] == 0 then
shifter_operand = Rm
shifter_carray_out = C flag
elif Rs[7:0] < 32 then
shifter_operand = Rm Logical_Shift_Right Rs[7:0]
shifter_carry_out = Rm[Rs[7:0] - 1]
elif Rs[7:0] == 32 then
shifter_operand = 0
shifter_carry_out = Rm[31]
else
shifter_operand = 0
shifter_carry_out = 0
7. 寄存器算数右移立即数寻址
语法:Rm>, ASR #<shift_imm>
if shift_imm == 0 then
shifter_carray_out = Rm[31]
if Rm[31] == 0 then
shifter_operand = 0
else
shifter_operand = 0xFFFF_FFFF
else
shifter_operand = Rm Arithmetic_Shift_Right shift_imm
shifter_carry_out = Rm[shift_imm - 1]
8. 寄存器算数右移寄存器寻址
语法:<Rm>, ASR <Rs>
if Rs[7:0] == 0 then
shifter_operand = Rm
shifter_carray_out = C flag
elif Rs[7:0] < 32 then
shifter_operand = Rm Arithmetic_Shift_Right Rs[7:0]
shifter_carry_out = Rm[Rs[7:0] - 1]
elif Rs[7:0] == 32 then
shifter_operand = 0
shifter_carry_out = Rm[31]
else
shifter_carry_out = Rm[31]
if Rm[31] == 0 then
shifter_operand = 0
else
shifter_operand = 0xFFFF_FFFF
9. 寄存器循环右移立即数寻址
语法:<Rm>, ROR #<shift_imm>
if shift_imm == 0 then
见“”介绍
else
shifter_operand = Rm Rotate_Right shift_imm
shifter_carry_out = Rm[shift_imm - 1]
10. 寄存器循环右移寄存器寻址
语法:<Rm>, ROR <Rs>
if Rs[7:0] == 0 then
shifter_operand = Rm
shifter_carray_out = C flag
elif Rs[4:0] < 32 then
shifter_operand = Rm
shifter_carray_out = Rm[31]
else
shifter_operand = Rm Rotate_Right Rs[4:0]
shifter_carry_out = Rm[Rs[4:0]- 1]
11. 寄存器扩展循环右移寻址
语法:<Rm>, RRX
shifter_operand = (C Flag Logical_Shift_Left 31) || (Rm Logical_Shift_Right 1)
shifter_carry_out = Rm[0]
边栏推荐
- ^33 variable promotion and function promotion interview questions
- How to view glibc version
- [cf1392d] D. Omkar and bed Wars
- conda环境下pip install 无法安装到指定conda环境中(conda环境的默认pip安装位置)
- 6.6 分離卷積
- redis 總結
- Arm cross compilation chain download address
- Golang基础(6)
- tensorflow 2. X multi classification confusion matrix and evaluation index calculation method (accuracy rate, recall rate, F1 score)
- Relatively rare exception records in UI automation test
猜你喜欢

C# 35. Select default network card

Reentrantlock source code analysis

redis 總結

Pytoch notes

DS18B20数字温度计 (一) 电气特性, 寄生供电模式和远距离接线

记录一下使用JPA时遇到的坑

InfoQ geek media's 15th anniversary solicitation |position:fixed virtual button cannot take effect after being triggered. Problem analysis and Solution Exploration

Basic principle of Doppler effect

Socket implements TCP communication flow

UML series articles (30) architecture modeling -- product diagram
随机推荐
Record the pits encountered when using JPA
字节序 - 如何判断大端小端
【蓝桥杯单片机 国赛 第十一届】
Drqueueonrails integrated LDAP authentication
go基于腾讯云实现发送短信
The difference between meta universe chain games and traditional games
Design of virtual scrolling list
systemctl里万恶的203
【数据库】sqlite版本升级、降级
arm交叉编译链下载地址
2022-06-11: note that in this document, graph is not the meaning of adjacency matrix, but a bipartite graph. In the adjacency matrix with length N, there are n points, matrix[i][j]
进程的创建和回收
信号继电器RXSF1-RK271018DC110V
tensorflow 2. X multi classification confusion matrix and evaluation index calculation method (accuracy rate, recall rate, F1 score)
Clj3-100alh30 residual current relay
6.6 分离卷积
Shardingjdbc-5.1.0 monthly horizontal table splitting + read-write separation, automatic table creation and node table refresh
Pytorch笔记
Redis keys in PHP
【clickhouse专栏】基础数据类型说明