GCC不节能/函数调用的恢复保留寄存器 [英] GCC not saving/restoring reserved registers on function calls

查看:203
本文介绍了GCC不节能/函数调用的恢复保留寄存器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在GCC造成我的问题的方案。我得到的行为是不是我期望的行为。总结的情况,我建议对X86-64这是在硬件仿真器实现了一些新的指令。为了测试这些说明我正在现有的C源$ C ​​$ c和使用十六进制handcoding新指令。因为这些指令与现有X86-64寄存器进行互动,我用的输入/输出/撞列表为GCC声明依赖。

这是怎么回事的是,如果我调用一个函数例如printf的,依赖寄存器不保存和恢复。

例如

 注册unsigned long类型R9 ASM(R9)= 101;
的printf(富%S \\ n,酒吧);
ASM挥发性(.BYTE为0x00,0x00时,0×00,0×00/ *无输出* /:Q(R9));

101被分配到R9和内联组件(假在本实施例)是依赖于R9。这正确运行在没有printf的,但是当它是存在的GCC不保存和恢复R9和另一个值是由有我的自定义指令调用的时候。

我想也许是GCC可能偷偷改变了分配到的变量的R9,但是当我这样做

  ASM挥发性(.BYTE%0:/ *无输出* /:Q(R9));

和看汇编输出,这的确是使用%R9。

我用gcc 4.4.5。你认为可能会发生呢?我以为GCC将永远保存和函数调用恢复寄存器。有一些方法可以让我执行呢?

谢谢!

编辑:顺便说一句,我在编译这样的程序

  gcc的-static -m64 -mmmx -msse -msse2 -O0 test.c的-o测试


解决方案

借助 ABI ,第3.2节.1说:


  

寄存器%RBP,RBX%和%R12到%R15属于调用函数和
  所谓功能
  需要preserve他们的价值观。换言之,一个叫函数必须preserve
  这些寄存器为它的调用者的值。剩余寄存器属于被叫
  功能。如果调用函数要preserve跨越这样一个寄存器值
  函数调用,它必须在其本地堆栈帧保存的价值。


所以你不应该通过R15%高于预期RBP%,%RBX以及R12%其他寄存器是通过函数调用pserved $ P $。

I have a scenario in GCC causing me problems. The behaviour I get is not the behaviour I expect. To summarise the situation, I am proposing several new instructions for x86-64 which are implemented in a hardware simulator. In order to test these instructions I am taking existing C source code and handcoding the new instructions using hexidecimal. Because these instructions interact with the existing x86-64 registers, I use the input/output/clobber lists to declare dependencies for GCC.

What's happening is that if I call a function e.g. printf, the dependent registers aren't saved and restored.

For example

register unsigned long r9  asm ("r9")  = 101;
printf("foo %s\n", "bar");
asm volatile (".byte 0x00, 0x00, 0x00, 0x00" : /* no output */ : "q" (r9) );

101 was assigned to r9 and the inline assembly (fake in this example) is dependent on r9. This runs correctly in the absence of the printf, but when it is there GCC does not save and restore r9 and another value is there by the time my custom instruction is called.

I thought perhaps that GCC might have secretly changed the assignment to the variable r9, but when I do this

asm volatile (".byte %0" : /* no output */ : "q" (r9) );

and look at the assembly output, it is indeed using %r9.

I am using gcc 4.4.5. What do you think might be happening? I thought GCC will always save and restore registers on function calls. Is there some way I can enforce it?

Thanks!

EDIT: By the way, I'm compiling the program like this

gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test

解决方案

The ABI, section 3.2.1 says:

Registers %rbp, %rbx and %r12 through %r15 "belong" to the calling function and the called function is required to preserve their values. In other words, a called function must preserve these registers’ values for its caller. Remaining registers "belong" to the called function. If a calling function wants to preserve such a register value across a function call, it must save the value in its local stack frame.

so you shouldn't expect registers other than %rbp, %rbx and %r12 through %r15 to be preserved by a function call.

这篇关于GCC不节能/函数调用的恢复保留寄存器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆