宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

我们编写的汇编程序还是不够底层,CPU都是对机器码进行操作的,所以还需要用汇编器将汇编代码转换成机器码才能被CPU处理。下面举几个例子来说说分析ARM机器码的方法。

  对编译连接之后得到的ELF进行反汇编:arm-linux-objdump

  查看得到的反汇编代码。这里如果想同时看到汇编代码和机器码,在编译的时候需要加上-g调试选项。

  1、mov r1,#0xff

    1110 00 1 1101 0 0000 0001 000011111111

  前者是汇编代码,后者是其对应的机器码。用第一个例子具体讲一下分析的方法。首先必须具备的一个手册就是ARM Architecture Reference Manual。这是学习ARM处理器绝对权威的一个参考资料。先看看每种ARM指令的一般格式

  ARM机器码分析-编程部落

ARM机器码分析-编程部落

  31–28是条件段,取值表如下所示

  ARM机器码分析-编程部落

  这里的例子中mov后面没有跟条件,所以是AL,Always (unconditional) ,对应的机器码为1110

  27–26为保留位,恒为00

  25位:Distinguishes between the immediate and register forms of <shifter_operand>. 

    标志shifter_operand段存放的是立即数还是寄存器。若为寄存器则置零,若为立即数则置一。

  24–21为opcode,标明指令的类型,下面是opcode的取值表

  ARM机器码分析-编程部落

  这个例子中mov对应的为1101

  20位:Signifies that the instruction updates the condition codes.

  表明该指令是否会影响程序状态字寄存器。是则置一,否则置零

  19–16位:Specifies the first source operand register.

  标明第一个源操作数寄存器,见每个指令的格式,有的有Rd,有的没有。

  由MOV指令的一般格式可以看出,他是没有使用Rd的,所以这几位填全0,其他使用到Rn的,这几位填通用寄存器标号的二进制值。如r2,则为0010

  15–12位:Specifies the destination register. 

  标明目的寄存器,填充方法同Rn

  11–0位:Specifies the second source operand.  

  标明第二个源操作数,若为立即数则填该立即数的二进制值,若为通用寄存器则填通用寄存器标号的二进制值。

  第一条指令的机器码到这里就分析完了,下面具其他几个不同的情况来验证上面的说法,分析方法还是一样的,这里就不一一分析了。

  

  2、 movne r2,r1
    0001 00 0 1101 0 0000 0010 000000000001

  3、 cmp r1,r2
    1110 00 0 1010 1 0001 0000 000000000010

  4、 add r0,r0,r1
    1110 00 0 0100 0 0000 0000 000000000001

  5、 bic r0,r1,#0b101
    1110 00 1 1110 0 0001 0000 000000000101

from: https://www.cnblogs.com/51qianrushi/p/4614491.html

bl指令机器码

ARM64:

B:0x17向前跳转,0x14向后跳转

BL:0x97向前跳转 0x94向后跳转

偏移地址计算过程:

(目标地址 – 指令地址)/ 4 = 偏移

// 减8,指令流水造成。

// 除4,因为指令定长,存储指令个数差,而不是地址差。

完整指令:

.text:000000000008CC84 8D B3 FF 97 BL je_arena_malloc_hard

.text:0000000000079AB8 je_arena_malloc_hard

计算偏移:

(79AB8-8CC84) / 4 = FFFFFFFFFFFFB38D

FFB38D | 0x97000000 = 97FFB38D

from: https://blog.csdn.net/lwanttowin/article/details/78385440