汇编中call指令和其对应的机器码

正文

call这个指令很神奇,他和别的指令不太一样

对比下,当我们执行

mov    eax,1

的时候,他的对应机器码是

66 B8 01 00 00 00

这其中“66 B8”对应的是“mov eax,x”
后面的“01 00 00 00”就是“1”在32位中的Little Endian了
所以说,在对mov指令进行汇编时,里面的常数会被直接汇编成机器码

然而call指令比较有意思
这个是一段很简单的汇编代码

Start:
    call    @F
@@:    pop        ebx

    call    @F
    nop
    nop
    nop
@@:    pop        ebx
    
    end    Start

然后通过反汇编后,他变成了这个样子
QQ截图20200413220226.png
仔细观察机器码和反汇编代码的对应关系,在汇编代码中,第一行的

call    @F
@F:    ......

被汇编成了机器码

E8 00 00 00 00

欸?“@F”所在地址明明是00401005,为什么没有被汇编成为

E8 05 10 40 00

呢?
再接着看下一个例子,这是汇编代码

call    @F
nop
nop
nop
@@:    ......

被编译器编译后变成了

E8 03 00 00 00

我好像发现了什么,编译器你好坏哦。。。
原来call编译后会把已call所在位置为基址,然后把被call的位置的偏移地址给汇编成字节码
编译器:你写的什么辣鸡玩意,让我来
我:我用od把你编译的东西全改了(:逃
开个玩笑,这个call的“隐藏”作用其实挺大的(大在哪?下次再写),改掉的话就傻*了~况且谁闲的没事改,偏移地址他不香吗(我在说什么,一个功能在这里水了5行)
现在我们把王爽的汇编语言(第3版)翻到第192页,我们看到执行

call    标号

的时候实际上在执行

push    eip
jmp    标号

(这段被我改成32位的了,书上是16位)
所以拓展下,jmp的原理和call其实是一样的,这里主要研究call
通过call这个特性,我们可以简单的做到重定位(作用就下一篇再写了)

其他发布

  1. https://blog.csdn.net/u013289971/article/details/105508135
  2. https://cqp.cc/t/49257

标签:技术报告

添加新评论