2

一切尽在标题中。由于某些原因,我必须这样做。

但是当我编译我的代码时,GCC(或者 GAS 可能......)显示以下错误:

.../Temp/cc1C1fjs.s:19:错误:立即操作数非法,绝对跳转

代码:

int main ( int argc, char **argv )
{
    /* Some code */

    ( (void(*)()) &&label)();

    /* Some code */

    return 0;

    label:
    asm ("push %ebp");
    asm ("mov %esp,%ebp");

    /* Some code */
    printf("Hello world");

    asm ("leave");
    asm("ret");
}

我确信这应该可行,因为我尝试使用 CreateThread 函数(我在 Windows 下)创建一个线程,将标签地址指定为入口点,并且效果很好。那么如何确保编译器接受这种语法呢?或者还有其他方法可以做到这一点?

4

2 回答 2

0

我解决了部分问题:

  1. @aix 你说得对,GCC 删除了 main 函数的所有内容return 0;,我修复了这个替换它

    asm("leave");
    asm("xor %eax,%eax");
    asm("ret");
    

    现在生成我的标签后的代码。

  2. gcc -S file.c然后 运行gcc file.s -o file.exe,当然它会显示错误,并且在错误行有call *$L2 (L2是我的c文件中的标签)。它通过将其替换为call L2.

    现在,在我的标签之后和我在 main 中调用之后的代码被执行,并且程序以状态 0 正确终止。

但我不想每次编译时都这样做。GCC写call *$L2而不是正常call L2吗?

于 2011-03-03T17:07:58.467 回答
0

我没有适合你的解决方案,但我有几个建议:

  1. 运行gcc -S file.c并查看第 19 行,看看您是否能发现实际问题。
  2. 查看(短)文件的其余部分,.s看看是否有明显问题。例如,我的版本gcc似乎决定之后的所有内容return 0都是死代码,所以你的asm代码都没有,也没有printf真正进入汇编程序。
  3. 这段代码不能移到函数中吗?这样你就可以免费获得序幕/尾声;取地址也不会那么困难。
于 2011-03-03T14:24:54.183 回答