2017-05-30 168 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

有沒有更好的方法來做棧對齊? –