gcc - 在调用函数( 使用推送指令) 之前的堆栈上,强制GCC输入参数

  显示原文与译文双语对照的内容
87 1

我已经开始在 gcc/G++ 下开发一个小型 16位 操作系统。 在下面的示例中,使用 CYGWIN ASM语法和命令行来编译/链接. CPP 文件的第一行:


G++: i586-elf-g++ -c $(CPP_FILE) -o $(OBJECT_OUTPUT) -nostdinc -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fpermissive -masm=intel



LD: i586-elf-ld -T $(LD_SCRIPT) $(OBJECT_OUTPUT) -o $(BINARY_OUTPUT)



我目前面临的问题是GCC将函数调用代码转换成程序集的方式。

GCC指令应该位于ESP中,而不是使用PUSH指令传递参数到 ESP,然后使用MOV指令,然后使用MOV指令手动写入堆栈。

这对我来说并不好,因为我依靠程序集代码中的推送指令。 要更清楚地说明我的问题,请使用以下 2函数:


void f2(int x);



void f1(){


 int arg = 8;


 asm("mov eax, 5");


 asm("push eax");


 f2(arg);


 asm("pop eax");


}


void f2(int x){


}



我将使用PUSH指令保存 EAX,并在调用f2和执行"pop EAX"指令后将它的恢复为 5. 然而,结果是EAX变成 8,而不是 5. 那是因为GCC生成的程序集代码看起来像这个( 为了清楚,我也包括了来源。):


void f1()


C++: {


 push ebp


 mov ebp,esp


 sub esp,byte +0x14



 C++: int arg = 8;


 mov dword [ebp-0x4],0x8



 C++: asm("mov eax, 5");


 mov eax,0x5



 C++: asm("push eax");


 push eax



 C++: f2(arg);


 mov eax,[ebp-0x4]


 mov [dword esp],eax =======>>>>>> HERE'S THE PROBLEM, WHY NOT 'PUSH EAX'?!!


 call f2



 C++: asm("pop eax");


 pop eax



C++: }


 o32 leave


 o32 ret



void f2(int x)


C++: {


 push ebp


 mov ebp,esp


C++: }


 pop ebp


 o32 ret



我尝试使用一些 G++ 编译标志,比如-mpush-args或者 -mno-push-args,另外一个我不记得了,GCC仍然不想使用 PUSH 。 我正在使用的版本是 i586-elf-g++ (GCC) 4.7.2 ( 在 CYGWIN 中重新编译的交叉编译器) 。

感谢你提前致谢 !

我发现了一个网页:我找到了一个网页: http://fixunix.com/linux/6799-gcc-function-call-pass-arguments-via-push.html

这对于GCC来说似乎很傻,考虑到它限制了 inline 程序集的可以用性。 ( 如果你有建议的话请留下答案) 。

时间: 原作者:

106 1

我非常幸运地找到解决这个问题的方法,但它最终是我想要做的。 以下是版本 4.7.2状态的GCC手册:


-mpush-args


-mno-push-args


Use PUSH operations to store outgoing parameters. This method is shorter


and usually equally fast as method using SUB/MOV operations and is enabled


by default. In some cases disabling it may improve performance because of


improved scheduling and reduced dependencies.



-maccumulate-outgoing-args


If enabled, the maximum amount of space required for outgoing arguments will


be computed in the function prologue. This is faster on most modern CPUs


because of reduced dependencies, improved scheduling and reduced stack usage


when preferred stack boundary is not equal to 2. The drawback is a notable


increase in code size. This switch implies '-mno-push-args'.



我是说我是幸运的,因为-mpush-args不起作用,工作是"-mno-accumulate-outgoing-args",甚至不是文档。

原作者:
...