下面以一段dis文件中代码来简单理解一下反汇编的读法(为了方便,部分说明已经卸载代码块双斜杠后面)
led.elf: file format elf32-littlearm //表明这是由led.elf文件反汇编得到的dis文件
//文件格式是elf32位的,且是小端模式存放
Disassembly of section .text: //说明反汇编文件是.text
00000000 <_start>: //标号地址、标号名字
0: e59f0050 ldr r0, [pc, #80] ; 58 <delay_loop+0x10>
4: e59f1050 ldr r1, [pc, #80] ; 5c <delay_loop+0x14>
8: e5810000 str r0, [r1]
指令地址 :号前面的数值
指令机器码 e59f0050这一列
指令机器码反汇编到的指令 ldr r0, [pc, #80] ; 58 <delay_loop+0x10>
【补充一小点:CPU工作原理】CPU通过访问指令地址,来访问指令机器码的
/*与上面反汇编代码对应的汇编代码*/
_start:
ldr r0, =0x11111111 // 从后面的=可以看出用的是ldr伪指令,因为需要编译器来判断这个数
ldr r1, =0xE0200240 // 是合法立即数还是非法立即数。一般写代码都用ldr伪指令
str r0, [r1] // 寄存器间接寻址。功能是把r0中的数写入到r1中的数为地址的内存中去
解读汇编与反汇编的关系:在反汇编中的这一句ldr r0, [pc, #80] 其实就是汇编语言中的ldr r0, =0x11111111
解读 0: e59f0050 ldr r0, [pc, #80] ; 58 <delay_loop+0x10>
首先上图,PC指向正被取指的指令,而非正在执行的指令(也就是说PC的地址值是正在执行代码的地址值加上8)。故PC的地址值应该是此时的指令地址值0+8,而[pc, #80]表示0+8+80=88,但是这是十进制的,十进制的88转换为十六进制为58,也就是我们后面可以看到的58。查看反汇编中的指令地址为0x58所对应的指令机器码如下图,可以看到0x58所对应指令机器码是11111111。到此为止可以看出反汇编文件中的 0: e59f0050 ldr r0, [pc, #80] ; 58 <delay_loop+0x10>与汇编文件中的ldr r0, =0x11111111的关系了吧?