汇编中的跳转

  汇编语言中有很多跳转,简单总结一下,以备后用。

  1. 相对跳转:
   JMP远跳,CALL编译成字节码的方法:
   jmp远跳与CALL指令都占5个字节
   JMP 32位目标地址
     E9 + (32位目标地址-下条指令地址)    或者说E9的下一条指令,加上 E9后面的值即为最终跳转目的地
     E9 + (32位目标地址-(当前指令地址+5))
   CALL 32位目标地址
     E8 + (32位目标地址-下条指令地址)
     E8 + (32位目标地址-(当前指令地址+5))
     减法运算直接使用无符号运算,而且遵循结果高高低低的存储规则,CPU自己会把结果当作有符号数来认。
   JMP近跳:
     JMP近跳占2个字节
       EB + (取低8位(32位目标地址-下条指令地址))
       EB + (取低8位(32位目标地址-(当前指令地址+2)))


  2. 绝对跳转

<pre name="code" class="cpp">// x64
000007fe`ff35c4a7 90              nop
ADVAPI32!RegQueryValueExA:
000007fe`ff35c4a8 ff25e2a40500    jmp     qword ptr [ADVAPI32!_imp_RegQueryValueExA (000007fe`ff3b6990)]
000007fe`ff35c4ae 90              nop

// x86
7545e14f 90              nop
ADVAPI32!RegQueryInfoKeyA:
7545e150 ff2570144575    jmp     dword ptr [ADVAPI32!_imp__RegQueryInfoKeyA (75451470)]
7545e14b 90              nop


  FF25 跳转指令,从当前ip(rip)跳转到目标地址。它的跳转方式是将当前的ip(rip)的值加上ff25指令后面的数字:

  例如:
    ff25e2a40500   跳转指令,要跳的最终目标地址为 000007fe`ff3b6990,当前的 rip的值为 000007fe`ff35c4ae ,FF25指令后的数字为 0x0005a4e2。

000007fe`ff3b6990 = 0x000007fe`ff35c4ae +0x0005a4e2

同理:x86 可得相同的情况。




你可能感兴趣的:(汇编中的跳转)