GCC将标签称为功能

时间:2011-03-03 01:56:54

标签: gcc label call gas

所有都在标题中。 出于某些原因,我必须这样做。

但是当我编译我的代码时,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下)创建一个线程,指定标签的地址作为入口点,并且它非常有效。 那么我怎样才能确保编译器接受这种语法呢? 或者有其他方法可以做到这一点?

2 个答案:

答案 0 :(得分:0)

我没有适合您的解决方案,但我确实有一些建议:

  1. 运行gcc -S file.c并查看第19行,看看您是否能发现实际问题。
  2. 查看(短).s文件的其余部分,看看是否有任何问题显然不对。例如,我的gcc版本似乎决定return 0之后的所有内容都是死代码,因此您的asm代码和printf都没有实际进入汇编程序。
  3. 这段代码不能移入函数吗?这样你就可以免费获得序幕/结语;拿着地址也不会那么困难。

答案 1 :(得分:0)

我解决了问题的一部分:

  1. @aix你有权利,GCC删除 一切主要功能 在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结束。

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