Mik*_*urg 20 c x86 gcc inline-assembly red-zone
我正在编写一个加密程序,并且核心(一个宽的乘法例程)是用x86-64汇编编写的,两者都是为了速度而且因为它广泛使用adc那些不容易从C中访问的指令.我不想内联这个函数,因为它很大,并且在内循环中被调用了好几次.
理想情况下,我还想为此函数定义一个自定义调用约定,因为它在内部使用所有寄存器(除外rsp),不破坏其参数,并在寄存器中返回.现在,它适应了C调用约定,但当然这使它变慢(大约10%).
为了避免这种情况,我可以调用它,asm("call %Pn" : ... : my_function... : "cc", all the registers);但有没有办法告诉GCC调用指令与堆栈混淆?否则GCC会将所有这些寄存器放在红色区域中,而顶部的寄存器将被破坏.我可以使用-mno-red-zone编译整个模块,但是我更喜欢告诉GCC,比方说,红色区域的前8个字节将被破坏,以便它不会放任何东西.
从你原来的问题我没有意识到gcc限制红区使用到叶子功能.我不认为这是x86_64 ABI所要求的,但它是编译器的合理简化假设.在这种情况下,您只需要将调用汇编例程的函数设置为非叶子以进行编译:
int global;
was_leaf()
{
if (global) other();
}
Run Code Online (Sandbox Code Playgroud)
GCC无法判断是否global为真,因此无法优化调用,other()因此was_leaf()不再是叶函数.我编译了这个(用更多代码触发堆栈使用)并观察到它作为一个叶子它没有移动,%rsp并且显示它做了修改.
我还尝试char buf[150]在一个叶子中简单地分配超过128个字节(只是),但我很震惊地看到它只进行了部分减法:
pushq %rbp
movq %rsp, %rbp
subq $40, %rsp
movb $7, -155(%rbp)
Run Code Online (Sandbox Code Playgroud)
如果我把失败的代码放回去了 subq $160, %rsp
不确定,但查看GCC 函数属性文档,我发现了stdcall可能感兴趣的函数属性。
我仍然想知道你发现你的 asm 调用版本有什么问题。如果只是为了美观,您可以将其转换为宏或内联函数。
| 归档时间: |
|
| 查看次数: |
1716 次 |
| 最近记录: |