我写了一个小程序来测试GCC的选项。
int main()
{
int a=0;
__asm__("movl %0,%%ecxn"
"jmp jmpsectionn"
"inc %%ecxn"
"jmpsection: movl $1,%%eaxn"
"movl $0,%%ebxn"
"int $0x80n"::"a"(a):"ecx","ebx");
}
为了使 var 等于 1,请跳过 inc 指令。我想强制 GCC 使用 IP 相对寻址方法生成 jmp 指令。我已经搜索了GCC手册以找到解决方案,但我犹豫不决。感谢您的重播。
对于 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。
当您在 GCC 中使用内联汇编时,汇编代码将直接传递给汇编程序。GCC 命令行选项不会更改汇编代码。您可以查看输出(使用 -S 选项)来验证这一点。编译器选项仅更改 GCC 从 C 代码生成程序集的方式。
因此,您需要查看汇编程序手册,而不是编译器手册。在您的情况下,GAS 可能会为jmp
选择短的 PC 相对编码,而无需指定任何选项。