上一篇文章对ARM下汇编的常用的指令进行了介绍,由于篇幅限制的原因,本文接着往下讲,主要介绍的内容是ARM汇编的伪指令的协处理器指令。
1. ARM 机器码(1) 机器码反汇编示例汇编程序执行流程 : 汇编代码 > 汇编器 > 机器码 > CPU 运行; 反汇编示例 : 找到一个 elf 文件, 使用 arm-linux-objdump 反汇编; 命令 : 使用 arm-linux-objdump -S -D start.elf 命令进行反汇编, 其中 "50008000:e3a01001 movr1, #1; 0x1" 中的 "e3a01001" 就是机器码, 如下图标注部分; 反汇编部分结果 : - [root@localhost 04_assembly]# arm-linux-objdump -S -D start.elf
- start.elf: file format elf32-littlearm
- Disassembly of section .text:
- 50008000 <_start>:
- .text
- .globl _start
- _start:
- mov r1,#1
- 50008000: e3a01001 mov r1, #1 ; 0x1
- mov r2,#2
- 50008004: e3a02002 mov r2, #2 ; 0x2
- mov r3,#3
- 50008008: e3a03003 mov r3, #3 ; 0x3
- Disassembly of section .debug_aranges:
复制代码 (2) 机器码格式
机器码格式 : 截图自 arm 文档 P110; ARM 机器码位数 : 32位; 机器码分段 : (3) 解析 MOV 指令机器码代码准备 : 汇编代码 : - .text
- .globl _start
- _start:
- mov r0, r1
- moveq r0, #0xff
复制代码Makefile 脚本 : - all:start.o
- arm-linux-ld -Ttext 0x50008000 -o start.elf $^
- [[[[[[%]]]]]].o:[[[[[[%]]]]]].S
- arm-linux-gcc -g -o $@ $^ -c
- clean:
- rm -rf *.o *.elf
复制代码反汇编 elf 文件 : 反汇编内容 : 省略下面的大部分; - [root@localhost 04_assembly]# arm-linux-objdump -S -D start.elf
- start.elf: file format elf32-littlearm
- Disassembly of section .text:
- 50008000 <_start>:
- .text
- .globl _start
- _start:
- mov r0, r1
- 50008000: e1a00001 mov r0, r1
- moveq r0, #0xff
- 50008004: 03a000ff moveq r0, #255 ; 0xff
- Disassembly of section .debug_aranges:
复制代码汇编对应机器码 : "mov r0, r1" : 十六进制 0xe1a00001, 二进制 11100001101000000000000000000001; "moveq r0, #0xff" : 十六进制 0x03a000ff, 二进制 00000011101000000000000011111111; 机器码解析 : 第一条 : 1110 00 0 1101 0 0000 0000 000000000001
第二条 : 0000 00 1 1101 0 0000 0000 000011111111 条件位对比 (第一段 31 ~ 28) : 第一条是 1110 对应 AL 总是执行, 第二条是 0000 对应 EQ; 保留位对比 (第二段 27 ~ 26) : 第一条 00, 第二条 00, 明显都一样; I 操作数类型标识位 (第三段 25) : 标志最后一个存立即数 还是寄存器, 如果是 0 表示寄存器, 如果是 1 表示立即数; 操作码位 (第四段 24 ~ 21) : 区分不同指令, 1101 是 MOV 指令; S 状态寄存器改变标识 (第五段 20) : 是否影响 CPSR 寄存器, 如果 S = 0 不影响, 如果 S = 1 影响; Rn 源操作寄存器 (第六段 19 ~ 16) : MOV 和 MVN 不使用 Rn 位, 寄存器编号; Rd 目的操作寄存器 (第七段 15 ~ 12) : 寄存器编号; shifter_operand 源操作书 (第八段 11 ~ 0) : 源操作数, 这个与 I 位结合起来, 如果 I = 0, 该位表示寄存器编号, 如果 I = 1, 该位表示 立即数大小, 立即数是有范围的, 如果超出会报错, 这里就需要使用伪指令了; 转自物联网博客:http://www.iotblog.cn/u/lixiaomei/b-192,转载请注明出处。
|