所有都在标题中。 出于某些原因,我必须这样做。
但是当我编译我的代码时,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下)创建一个线程,指定标签的地址作为入口点,并且它非常有效。 那么我怎样才能确保编译器接受这种语法呢? 或者有其他方法可以做到这一点?
答案 0 :(得分:0)
我没有适合您的解决方案,但我确实有一些建议:
gcc -S file.c
并查看第19行,看看您是否能发现实际问题。.s
文件的其余部分,看看是否有任何问题显然不对。例如,我的gcc
版本似乎决定return 0
之后的所有内容都是死代码,因此您的asm
代码和printf
都没有实际进入汇编程序。 答案 1 :(得分:0)
我解决了问题的一部分:
@aix你有权利,GCC删除
一切主要功能
在return 0;
之后,我解决了这个问题
替换它
asm("leave");
asm("xor %eax,%eax");
asm("ret");
现在生成标签后的代码。
然后运行gcc -S file.c
gcc file.s -o file.exe
,当然它显示错误并且在
错误行有call *$L2
(L2是我的c文件中的标签)。有用
将其替换为call L2
。
现在我的标签之后的代码和我在main之后的电话是 执行和程序正常 以状态0结束。
但是每次我编译时我都不想这样做。
GCC写call *$L2
而不是call L2
是否正常?