反汇编解析S3C2440汇编点灯

目录

    • 代码
    • 反汇编
      • 对比
      • 解析
      • 总结
    • dis和bin对比

代码

首先回顾代码

/*
*点亮LED:GPF4
*/
.text //表明它是代码段
.global _start

_start:

/*配置GPF4为输出引脚
*把0x100写到地址0x56000050上,熄灭led
*/
	ldr r1, =0x56000050  	/*将这个地址存放到r1中*/
	ldr r0, =0x100			/*或者使用 mov r0, #0x100  将0x100放入r0 */ 
	str r0, [r1]			/*将r0的值写入到r1的地址中*/

/*设置GPF4输出高电平
*把0x00写到地址0x56000054上,点亮led
*/
	ldr r1, =0x56000054  	/*将这个地址存放到r1中*/
	ldr r0, =0				/*或者使用 mov r0, #0x100  将0放入r0 */ 
	str r0, [r1]			/*将r0的值写入到r1的地址中*/


halt:						/*假设这个程序只有十几个字节*/
	b halt					/*这十几个字节后的内容是不确定的,所以要让他在这里死循环*/

我们使用的ldr是伪指令,将地址存放在r1和r0中
伪指令,就是假的arm指令
它对应哪些真正的arm指令呢

反汇编

要想知道这个伪指令对应的真正的arm指令
我们就需要将elf文件反汇编
反汇编解析S3C2440汇编点灯_第1张图片

arm-linux-objdump -D led.elf  > led.dis

输入指令反汇编
将生成的dis文件传到windows,并使用notepad打开
反汇编解析S3C2440汇编点灯_第2张图片

对比

反汇编解析S3C2440汇编点灯_第3张图片
左侧是我们使用的伪指令
可以看到真实的arm指令,是将这个地址放在内存中,使用pc读取内存中1c和20的地址给r1

第二条指令直接使用mov,将地址存放在r0当中

解析

2440中有CPU,CPU中有r0到r15,16个寄存器。这里是如何使用PC值来表示寄存器呢
反汇编解析S3C2440汇编点灯_第4张图片

  • pc——Program Counter(程序计数器)
    当你把一个地址写道R15也就是程序计数器时,程序就跳到那个地址中去
    地址为当前指令的地址+8

  • lr——Link Register(返回地址)
    使用函数调用的时候,执行完毕要跳回原来的地方。R14/lr就是用来保存原来的地址

  • st——Stack Pointer(栈指针)

反汇编解析S3C2440汇编点灯_第5张图片
PC是什么?
当前指令的地址使0,PC的地址是当前指令加8
因为ARM系统里面,为了使执行效率更加高,CPU是以流水线的方式执行的

  • 流水线:当前执行地址A的指令;已经在对地址A+4的指令进行译码;已经在读取地址A+8(PC)的指令。

对于上面的图
r1的值,等于[pc+20]这个地址的值,等于[8+20],28对应16进制就是0x1c
即,r1的值,就是0x1c地址中存放的值,就是0x5600,0050

第三条指令,将0x100写入r1对应的内存,就是把0x100写入0x5600,0050

第四条指令,r1等于[pc+12]=[0xc+8+12]=[32]=[0x20]
即,去0x20这个地址读取值,存放到r1里面,就是0x5600,0054

总结

在程序里面,寄存器和内存没有本质的差别。CPU都把它们当作内存来使用
只是这些内存比较特殊,配置他们能控制一些引脚

dis和bin对比

dis是反汇编文件
反汇编解析S3C2440汇编点灯_第6张图片我们知道,bin文件中都是二进制的机器码,那么我们来对比以下dis的汇编码和bin中的机器码
反汇编解析S3C2440汇编点灯_第7张图片
可以看到是完全一致的
反汇编dis文件中的汇编码的源头们就是我们编写的代码,那些伪指令和汇编码
步骤如下

  • 编译器将伪指令转化为真正的汇编码,对于真正的汇编码保持不变
  • 转换完成后,将所有的汇编码转换为机器码,然后存为bin文件。这些bin文件就可以直接烧写到单板上了。

你可能感兴趣的:(S3C2440,汇编相关,裸机相关,S3C2440,JZ2440,裸机开发)