我有一个用64位x86汇编语言编写的函数(用于gcc和GAS的AT&T语法),它执行一些SSE2操作.我通过使用反汇编的gdb并查看寄存器值来检查结果,所以我知道它产生了正确的结果.在retq指令之后,我得到了一个segementation故障.因为我刚接触汇编(并且从未接受过任何类),我猜我没有正确处理函数/主程序接口.该函数接受2个指针和一个int,并期望返回一个浮点数.这就是我在汇编函数中处理输入/输出的方法:
float foo(float *x,float *y,unsigned int s)
{
__asm__ __volatile__(
"movl -0x14(%%rbp),%%ecx \n\t" //ecx = s
"movq -0x8(%%rbp),%%rax \n\t" //rax -> x
"movq -0x10(%%rbp),%%rdx \n\t" //rdx -> y
"subq $4,%%rsp \n\t" //function result
#sse2 operations that end up with the answer in xmm4...
"movss %%xmm4,(%%rsp) \n\t" //store result
"flds (%%rsp) \n\t" //load function result
"addq $4,%%rsp \n\t" //adjust stack
"ret \n\t"
:
:"g"(s)
:"%ecx","%rax","%rdx"
);
}
Run Code Online (Sandbox Code Playgroud)
这里的行似乎导致了segfault(在反汇编中ret之后的指令):
0x00007fffffffe0d0 in ?? ()
=> 0x00007fffffffe0d0: 00 00 add %al,(%rax)
Run Code Online (Sandbox Code Playgroud)
我不知道为什么它在执行我的函数后将rax的低位中的值添加回rax,但它似乎崩溃了.我不允许在我的汇编函数中使用rax,即使它是一般用途并且我宣布它被破坏了吗?
我不确定你是否需要看到这个部分,但这是gcc期望处理该功能的方式; 我已经包含了调用我的函数的行的反汇编: …