【问题标题】:How to generate IP relative addressing instructions with GCC如何使用 GCC 生成 IP 相对寻址指令
【发布时间】:2012-04-20 13:13:55
【问题描述】:

我写了一个小程序来测试 GCC 的选项。

int main()
{
    int a=0;
    __asm__("movl %0,%%ecx\n"
            "jmp jmpsection\n"
            "inc %%ecx\n"
            "jmpsection: movl $1,%%eax\n"
            "movl $0,%%ebx\n"
            "int $0x80\n"::"a"(a):"ecx","ebx");
}

为了保持 var a 等于 1,请跳过 inc 指令。 我想强制 GCC 使用 IP 相对寻址方法生成 jmp 指令。 我搜索了 GCC 手册以找到解决方案,但我失败了。 感谢重播。

【问题讨论】:

标签: c linux assembly x86


【解决方案1】:

对于 x86,IP 相对寻址只能在长模式(64 位)下使用,而且您似乎正在编写 32 位代码。

编辑:实际上,在 32 位模式下, 可以相对于当前 IP 进行跳转,我认为编译器实际上会根据您的情况生成正确的代码。我们来看看生成的程序集的相关部分:

00000000 <main>:
  ...
  13:   eb 01                   jmp    16 <jmpsection>
  15:   41                      inc    %ecx

00000016 <jmpsection>:
  16:   b8 01 00 00 00          mov    $0x1,%eax
  ...

因此,虽然它看起来像地址 13 处的指令直接跳转到地址 16,但它实际上 一个 IP 相对跳转。看一下机器码:

eb 01

eb 是具有 8 位位移的短 jmp 的操作码。 01 就是这个位移。该指令的结果是跳转到%eip + 0x01,并且由于IP 指向要执行的下一个 指令,这将跳转到地址16。

【讨论】:

  • 我不这么认为。 Smashing The Stack For Fun And Profit 在这篇文章中,作者使用IP相对寻址编写了shellcode。从 shellcodeasm.c 中的反汇编代码中你可以看到。
  • @Job 为什么是8bits位移?
  • 并且它总是使用相对于下一条指令的位移的近调用吗?如果它在给出地址时使用远调用怎么办。在这种情况下,我们无法获得偏移量?
【解决方案2】:

当您在 GCC 中使用内联汇编时,汇编代码只是直接传递给汇编器。 GCC 命令行选项不会更改您的汇编代码。您可以验证查看输出(使用 -S 选项)。编译器选项只会改变 GCC 从 C 代码生成程序集的方式。

因此,您需要查看assemblers manual,而不是编译器手册。在您的情况下,GAS 可能会为 jmp 选择短 PC 相关编码,而无需指定任何选项。

【讨论】:

    猜你喜欢
    • 2018-07-08
    • 2017-01-07
    • 1970-01-01
    • 2017-12-11
    • 2017-05-15
    • 2015-01-03
    • 2013-04-07
    • 1970-01-01
    • 2020-04-29
    相关资源
    最近更新 更多