GCC 将标签作为函数调用

发布于 2024-10-20 04:39:59 字数 565 浏览 3 评论 0原文

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

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

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

代码:

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 下)创建一个线程,指定标签地址作为入口点,并且它工作得很好。 那么如何确保编译器接受这个语法呢? 或者还有其他方法可以做到这一点?

All is in the title.
For some reasons I have to do it like this.

But when I compile my code, GCC (or GAS maybe...) displays the following error:

.../Temp/cc1C1fjs.s:19: Error: immediate operand illegal with absolute jump

Code:

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");
}

I'm sure that this should works because I tried to create a thread using CreateThread function (I'm under windows) specifing as entry point the address of label, and it works perfectly well.
So how can I ensure that the compiler accepting this syntax?
Or there is anothers ways for doing that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一抹淡然 2024-10-27 04:39:59

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

  1. 运行 gcc -S file.c 并查看第 19 行,看看您是否可以发现实际问题是什么。
  2. 查看(短).s 文件的其余部分,看看是否有任何明显错误。例如,我的 gcc 版本似乎决定 return 0 之后的所有内容都是死代码,因此您的 asm 代码和 >printf 实际上将其发送到汇编器。
  3. 这段代码不能移到函数中吗?这样你就可以免费获得序言/尾声;获取地址也不会那么困难。

I don't have a solution for you, but I do have a couple of suggestions:

  1. Run gcc -S file.c and look at line #19 to see if you can spot what the actual problem is.
  2. Look through the rest of the (short) .s file to see if anything is obviously amiss. For example, my version of gcc seems to decide that everything after return 0 is dead code, so none of your asm code nor the printf actually make it to the assembler.
  3. Can't this code be moved into a function? This way you'll get the prologue/epilogue for free; taking the address would also be less fraught with difficulty.
一片旧的回忆 2024-10-27 04:39:59

我修复了部分问题:

  1. @aix 你说得对,GCC 删除
    主要功能的一切
    return 0; 之后,我修复了这个问题
    将其替换为

    asm("离开");
    asm("异或%eax,%eax");
    asm(“ret”);
    

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

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

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

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

I fixed a part of the problem:

  1. @aix you have right, GCC remove
    everything of the main function
    after return 0;, I fixed this
    replacing it by

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

    Now the code after my label is generated.

  2. Running gcc -S file.c then
    gcc file.s -o file.exe, of course it displays the error and at
    the error line there is call *$L2
    (L2 is label in my c file). It works
    by replacing it by call L2.

    Now the code after my label and after my call in main is
    executed and the program properly
    terminates with state 0.

But I don't want to have to do that each time I will compile.
Is it normal that GCC write call *$L2 rather than call L2?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文