|

楼主 |
发表于 2019-6-27 11:30:59
|
显示全部楼层
(* 标准ALU指令 ADD/SUB/ADC/SBC/RSB/RSC /CMP/CMN/TST/TEQ/MOV/MVN /BIC/AND/ORR/EOR
(*----------*_*)
ADD/SUB 正常加减 举个例子 ADD Rd, Rn, Rm (Rm+Rn放进Rd寄存器中)
ADC/SBC 带进位加减 SBC是结果进位C清零
RSB/RSC 反序减法(RSC带进位) RSB Rd, Rn, Rm (Rm-Rn放进Rd寄存器中)
CMP/CMN 行为类似ADD/SUB, CMP对应ADD, CMN对应SUB.但是不保持结果, 用于测试执行结果
AND 操作数相与
ORR 操作数相或
EOR 操作数异或
TST 操作数相与不保持结果, 用于测试执行结果
TEQ 操作数异或不保持结果, 用于测试执行结果
BIC 操作数与第二个操作数取反相与
MOV 寄存器之间互相拷贝
MVN 寄存器取反拷贝
除了CMP/CMN/TST/TEQ外都能设置是否影响标志位, 而这几个都会影响标志位, 无论是否设置.
这些ALU指令都有一个统称的Oprand2, 一共12位
这个Oprand2根据不同需求会被分别解释成三种类型的寻址计算
1. 8位立即数+4位偶数移位数 扩展成32位立即数, 注意,这个移位是循环右移, 并且也可能因为设置影响C位
2. 5位移位立即数+移位类型+Rm, 这个跟上面LDR用的移位是一样的, 不同的是某些指令设置影响标志位时,
移位进位会进入C位 (Rs移位也如此)
这个C位是否影响标志位取决于所执行的指令是否影响C位,
如果本身也影响将会忽略移位的C位进位
当然ALU指令没有设置影响标志也不会测试C位, Rs移位也是一样
3. Rs移位寄存器+移位类型+Rm
差不多, 跟上面一样, 移位量取最低的一个字节, 多了对>=32移位量的判断,
使用Rs移位会增加一个I周期
具体情况如下, 只写特殊情况了, 常规操作不写了,大家应该都懂的:
对于所有Rs移位 Rs:=0, 都是 Operand2 = Rm, C 不变
LSL-#Imm5bit
#Imm5bit = 0 Operand2 = Rm, 不影响C位
LSL-Rs
Rs = 32 Operand2 = 0, C:= Rm bit0
Rs > 32 Operand2 = 0, C := 0
LSR-#Imm5bit
#Imm5bit = 0 Operand2 = 0, C:= Rm bit31
LSR-Rs
Rs = 32 Operand2 = 0, C:= Rm bit31
Rs > 32 Operand2 = 0, C := 0
ASR-#Imm5bit
#Imm5bit = 0 Operand2 = (Rm bit31)? 0 :0xFFFFFFFF:, C:= Rm bit31
ASR-Rs
Rs = 32 Operand2 = 0, C:= Rm bit31
Rs > 32 Operand2 = (Rm bit31)? 0 :0xFFFFFFFF:, C:= Rm bit31
ROR-#Imm5bit
#Imm5bit = 0 RRX
ROR-Rs
if Rslo5bit = 0 Operand2 = Rm, C:= Rm bit31
else 基本操作, 此模式只使用低5位.
Operand2 3种形式格式
1. 八位循环移位+ROR Operand2:= Imm32:= Imm8 >> (Shift*2)
2. Shift+Imm5 Operand2:= Rm ShiftType ShiftImm5bit
3. Shift+Rs Operand2:= Rm ShiftType Rs's Byte
各种形式都举几个例子哈!, Oprand2具体形式位域编码见后面机器码表
1. 八位移位+ROR MOV R1, #0x80000000
2. Shift+Imm5 MOV R1, R0, LSL #2
SBC R1, R0, RRX
2. Shift+Rs MOV R1, R0, LSL R2
MOVS R1, R0, LSL R2 ;; MOVS, S表示同时设置标志位
``````````````` ADD/SUB/ADC/SBC/RSB/RSC/CMP/CMN
这几个操作数都是相加,相减
对于 保持结果到Rd的指令有 Rd, Rn, Operand2 形式的操作
对于 比较不保持结果的指令 不使用Rd位域, 即使他是有位域编码存在, 只有 Rn, Operand2 形式的操作
对于 比较不保持结果的指令设置S与否始终会设置标志位 .
这些指令都会影响NZCV标志位 (如果设置了S标志位)
对于带进位减法指令, 当C位为0, 会额外减去一个1, 跟带进位加法相反!, thumb指令的alu也是如此
``````````````` AND/ORR/EOR/TST/TEQ
这几个操作数都是逻辑操作
对于 保持结果到Rd的指令有 Rd, Rn, Operand2 形式的操作
对于 比较不保持结果的指令 不使用Rd位域, 即使他是有位域编码存在, 只有 Rn, Operand2 形式的操作
对于 比较不保持结果的指令设置S与否始终会设置标志位 .
这些指令都会影响NZ标志位 (如果设置了S标志位, C位看移位类型了, 否则不影响)
``````````````` MOV/MVN/BIC
这几个操作数都是寄存器之间传输操作
都是 Rd, Rn, Operand2 形式的操作
这些指令都会影响NZ标志位 (如果设置了S标志位, C位看移位类型了, 否则不影响)
(* 主ALU 机器码
(***********_*)
27 26 25 24 23 22 21 20 19 - 16 15 - 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 I Opcode S Rn Rd Operand2
oprand2: 编码1 (I =1) : 4位移位+8位数据 d0-d7 8位立即数, d8-d11 4位偶数移位数
编码2 (I =0 && d4=0) : 寄存器移位 5位移位量(d11-d7)+2位移位类型(d6-d5)+4位寄存器索引(d3-d0)
编码3 (I =0 && d4=1 && d7 = 0) :
寄存器RS移位 RS寄存器索引(d11-d8)+2位移位类型(d6-d5)+4位寄存器索引(d3-d0)
Opcode指示具体的 ALU/逻辑处理指令 - 操作模式
0: AND Rd,Rn,Operand2
1: EOR Rd,Rn,Operand2
2: SUB Rd,Rn,Operand2
3: RSB 反序 Sub Rd,Rn,Operand2
4: ADD Rd,Rn,Operand2
5: ADC Rd,Rn,Operand2
6: SBC Rd,Rn,Operand2
7: RSC 反序 Sbc Rd,Rn,Operand2
8: TST Rn,Operand2 (S位域必为1, 同时如果是Rs/Imm5移位寻址会测试移位C来设置CPSR的进位状态位)
9: TEQ XOR不保持结果 Rn,Operand (S位域必为1, 同时如果是Rs/Imm5移位寻址会测试移位C来设置CPSR的进位状态位)
A: CMP Rn,Operand2 (S位域必为1)
B: CMN A+B不保持结果 Rn,Operand2 (S位域必为1)
C: ORR OR Rd,Rn,Operand2
D: MOV Rd,Operand2
E: BIC 位清理 Rd,Rn,Operand2, rd:= rd & ~rn
F: MVN 取反MOV Rd,Operand2 rd := ~rm
SUB/ADD/ADC/SBC/CMP/CMN/RSB/RSC 设置NZCV
EOR/ORR/AND/TST/TEQ/BIC/MVN/MOV 设置NZC-(C由移位Operand2获得)
S表示是否设置CPSR标志位, 1设置0不设置
对于ALU操作中具有Rd参数且设置S标志的指令且Rd=PC的情况下
会把当前模式下的SPSR缓存PSR拷贝到CPSR切换模式, 此细节一般用于从中断返回.
举几个中断返回的例子,
未定义指令: MOVS PC, LR
预取异常: SUBS PC, LR, #4 (中断时候加上的微小的, 无用的偏移量, 需要减去,才能返回到正确的地址)
访存异常: SUBS PC, LR, #8 (中断时候加上的微小的, 无用的偏移量, 需要减去,才能返回到正确的地址)
|
|