如何使用GCC生成IP相对寻址指令

时间:2012-04-20 13:13:55

标签: c linux assembly x86

我写了一个小程序来测试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等于1,跳过inc指令。 我想强制GCC使用IP相对寻址方法生成jmp指令。 我已经搜索了GCC手册以找到解决方案,但我很满意。 感谢重播。

2 个答案:

答案 0 :(得分:3)

对于x86,只能在长模式(64位)中进行IP相对寻址,并且您似乎正在编写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指向要执行的 next 指令时,这将跳转到地址16.

答案 1 :(得分:1)

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

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