2017-05-30 170 views
0

我不擅长汇编语言。我正试图调用一个函数foo,它需要10个浮点参数。在前八个之后,使用xmm0-xmm7寄存器,将参数压入堆栈。除了最后两个浮点值之外,我得到了几乎正确的结果,这是我放入堆栈的那些值。如何使用ABI调用过程正确传递堆栈上的浮点参数

我认为我的错误是我如何调用push,并与值保持一致。虽然我不确定,但我一直无法找出解决方案。我认为这将是一个相当简单的修复。

下面是一个例子一块的什么,我想实现代码:

#include <iostream> 

void* foo(float a_, float b_, float c_, float d_, float e_, float f_, float g_, float h_, float i_, float j_) 
{ 
    std::cout << "A=" << a_ << std::endl; 
    std::cout << "B=" << b_ << std::endl; 
    std::cout << "C=" << c_ << std::endl; 
    std::cout << "D=" << d_ << std::endl; 
    std::cout << "E=" << e_ << std::endl; 
    std::cout << "F=" << f_ << std::endl; 
    std::cout << "G=" << g_ << std::endl; 
    std::cout << "H=" << h_ << std::endl; 
    std::cout << "I=" << i_ << std::endl; 
    std::cout << "J=" << j_ << std::endl; 
    return NULL; 
} 

struct asm_call_data 
{ 
    void* (*_function)(...); 
    float _data[10]; 
}; 

int main() 
{ 
    asm_call_data call_data; 

    call_data._function = (void* (*)(...))&foo; 
    call_data._data[0] = 1.3; 
    call_data._data[1] = 2.4; 
    call_data._data[2] = 3.5; 
    call_data._data[3] = 4.7; 
    call_data._data[4] = 5.8; 
    call_data._data[5] = 6.9; 
    call_data._data[6] = 7.0; 
    call_data._data[7] = 8.1; 
    call_data._data[8] = 9.2; 
    call_data._data[9] = 10.3; 

    __asm__ __volatile__ (
     // create new stack frame 
     "pushq %%rbp;\r\n\t" 
     "movq %%rsp, %%rbp;\r\n\t" 
     // move call data _data values into xmm0, xmm1, xmm2 
     "movss 8(%%rax), %%xmm0;\r\n\t" 
     "movss 12(%%rax), %%xmm1;\r\n\t" 
     "movss 16(%%rax), %%xmm2;\r\n\t" 
     "movss 20(%%rax), %%xmm3;\r\n\t" 
     "movss 24(%%rax), %%xmm4;\r\n\t" 
     "movss 28(%%rax), %%xmm5;\r\n\t" 
     "movss 32(%%rax), %%xmm6;\r\n\t" 
     "movss 36(%%rax), %%xmm7;\r\n\t" 
     "push 40(%%rax);\r\n\t" 
     "push 44(%%rax);\r\n\t" 
     // align stack 
     "andq $-16, %%rsp;\r\n\t" 
     // make asm call 
     "call 0(%%rax);\r\n\t" 
     // restore stack frame 
     "movq %%rbp, %%rsp;\r\n\t" 
     "popq %%rbp;\r\n\t" 
    : 
    : "a"(&call_data) 
    : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" 
    ); 
} 

以下是编译和运行时,我得到的输出。我不知道警告真的告诉了我什么,在'我='我有一个非常数字,但以下数字是正确的。

[email protected]:~/Documents/Subproject$ g++ Main.cpp -o Main 
Main.cpp: Assembler messages: 
Main.cpp:78: Warning: indirect call without `*' 
[email protected]:~/Documents/Subproject$ ./Main 
A=1.3 
B=2.4 
C=3.5 
D=4.7 
E=5.8 
F=6.9 
G=7 
H=8.1 
I=4.51567e+27 
J=10.3 
[email protected]:~/Documents/Subproject$ 

有关如何解决此问题的任何想法?组件的其余部分是否正确?而且,警告告诉我什么?我的代码中没有第78行..

+1

这是什么指令集?我假定x86? –

+0

嘿,它实际上在64位上运行。 –

+1

应该指出这个代码中的重大失败。它可以打破红色区域。 –

回答

1

如果您正在进行堆栈对齐,您需要在之前执行推送您的参数。

而且,由于C++从右向左推送参数,因此需要在Idata[8])之前推Jdata[9])。

+0

有没有更好的方法来做栈对齐? –