Skip to content

Commit 4ce317c

Browse files
committed
arm mov
1 parent d928be6 commit 4ce317c

File tree

6 files changed

+93
-0
lines changed

6 files changed

+93
-0
lines changed

Android/C03/README.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
## 1.1 mov
2+
3+
> 如何快速从arm手册查看指令 F5:T32 and A32--F5.1
4+
5+
```python
6+
mov指令,不访问内存,没有读写内存的操作。因为不访存所以没有内存操作数,只有两个操作数要么是寄存器要么是立即数。
7+
从第二个操作数给第一个操作数,所以第一个操作数一定是寄存器。
8+
arm指令长度就是4字节32位,立即数不能是任意的32位整形,指令长度不足以表示。
9+
因为mov三种格式允许操作的立即数最多的就是A2编码16位,所以mov指令下立即数不能超16位。
10+
```
11+
12+
### 1.1.1 MOV, MOVS (immediate)
13+
14+
#### A1
15+
16+
![](pic/01.png)
17+
18+
```
19+
mov r0,0x80000000 即使立即数超了16位也可以,为什么呢?因为采用了A1的这种方式,这种立即数比较常见,它的有效位只有它的最高位。
20+
02 01 A0 E3 MOV R0, #0x80000000
21+
22+
hex_str1 = "0xE3a00102"
23+
bin:1110 0011 1010 0000 0000 0001 00000010
24+
25+
图上又把后12位拆成2份,8-11位以及0-7位,机器码里面的02也就是低8位立即数00000010进行向右循环移位。移多少位呢,就是imm12的高第8-11位乘2,也就是最后8位2向右移动0001*2也就是两位。
26+
27+
此指令A1作用就是 防止写入0x80000000时把机器码弄长,采用左移的方式。
28+
```
29+
30+
#### A2
31+
32+
![](pic/02.png)
33+
34+
```
35+
mov 寄存器,立即数。往寄存器写任意一个16位(imm12+imm4=16)的立即数,所以imm一定不能超过16位,0x1234可以,0x12345不行。
36+
37+
34 02 01 E3 MOV R0, #0x1234
38+
hex_str = "0xE3010234"
39+
bin: 1110 0011 0000 0001 0000 001000110100
40+
41+
34 12 01 E3 MOV R1, #0x1234
42+
hex_str1 = "0xE3011234"
43+
bin:1110 0011 0000 0001 0001 001000110100
44+
45+
倒数第1块后12位(imm12)就是立即数后三个字节0x234,倒数第3块4位(imm4)就是立即数第一个字节0x1,拼起来就是我们的立即数0x1234。
46+
倒数第2块Rd就是代表寄存器,12-15有4位,2的4次方可以表示0-15的数字,int("1111", 2)=15也就是寄存器r0-r15,后三个寄存器就是SP、LR、PC。此时我们是r0,看倒数第二块就是0,r1就是0001。
47+
bin(16) =0b10000,16以后只能5位才能表示。
48+
第20位是1的话就是movs
49+
```
50+
51+
```
52+
如何使用mov指令在一个寄存器里写入一个任意的32位立即数?
53+
首先使用mov写入低16位, mov r0, #0x5678,在使用movt在下一条汇编写入高16位, MOVT R0, #0x1234
54+
ida会自动把两句混成一句,ida会生成一个伪指令,78 06 05 E3 34 02+ mov r0, #0x12345678
55+
arm指令时定长的,它是编译器生成的伪指令。
56+
```
57+
58+
### 1.1.2 MOV, MOVS (register)
59+
60+
#### A1
61+
62+
![](pic/03.png)
63+
64+
```
65+
mov r0, r1(寄存器,寄存器)
66+
mov寄存器可以带shift的, 01 02 A0 E1 MOV R0, R1,LSL#4, r1左移4位给r0
67+
此指令两个操作数 第一个r0,第二个操作数R1,LSL#4 左移4位
68+
69+
hex_str = "0xE1A00201"
70+
bin:1110 0001 1 01 0 0000 0000 0010 000 0 0001
71+
72+
Rm = 0001 = r1, 操作的寄存器
73+
stype = 00 = LSL
74+
左移右移通过stype(5-6)两位表示,2的2次方代表4种模式:逻辑左移、逻辑右移、算术右移、循环移位。
75+
没有算数左移,因为算数左移和逻辑左移是一样的,算术右移是带符号的不等于逻辑右移,循环移位不区分左右。
76+
imm5 = 移位的位数 = 00100 = 4
77+
移位的数就是imm5,这里imm5不是指立即数而是移多少位,7-11位就是通过5位表示,2的5次方=32。
78+
移位的范围是32,因为循环左移1位和循环右移31位是一样的,所以循环移位不区分左右。
79+
Rd = 0000 = r0
80+
81+
lsl r0, r1,4 = MOV R0, R1,LSL#4
82+
相当于mov指令的宏,另一种写法,ida在翻译的时候都会给翻译成mov指令,所以在ida反编译界面找不到lsl、lsr这种指令,都给翻译成了mov指令。
83+
```
84+
85+
### 1.1.3 MOV, MOVS (register-shifted register)
86+
87+
![](pic/04.png)
88+
89+
```
90+
MOV R0, R1,LSR R2 同上,只不过imm5立即数换成了Rs,与lsr r0, r1, r2两种相等,反汇编后都是move指令。
91+
```
92+

Android/C03/pic/01.png

9.63 KB
Loading

Android/C03/pic/02.png

9 KB
Loading

Android/C03/pic/03.png

10.8 KB
Loading

Android/C03/pic/04.png

10.9 KB
Loading

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959

6060
- [01.环境搭建](Android/C01/README.md)
6161
- [02.寄存器和指令基本格式](Android/C02/README.md)
62+
- [03.基本运算](Android/C03/README.md)
6263

6364
----
6465

0 commit comments

Comments
 (0)