2014-10-20 80 views
4

我們的課程練習要求我們在GNU彙編中創建delta = b2-4ac函數,並從C中訪問它。由於這是一門關於編譯器的課程,而不是彙編,所以教授選擇只展示整數功能,並期望一個整數函數。訪問彙編函數的浮點返回

但是,我希望個人學習稍微超出責任範圍,創建一個返回浮點而不是整數的可用函數。

我想出了這個C(dont't介意全局,下一個練習的目的是有參數的適當功能):

# include <stdio.h> 

extern float delta(); 
float a, b, c; 

int main() { 
    a = 3; 
    b = 5; 
    c = 4; 
    printf("δ = %f\n", delta()); 
    return 0; 
} 

這GNU GAS:

.globl a 
.globl b 
.globl c 
.globl delta 
.f4: .float 4.0  # constante 4 

.text 
delta: 
    fld b   # b sur la pile 
    fmul b   # b2 sur la pile 
    fld .f4   # 4 sur la pile 
    fmul a   # 4a sur la pile 
    fmul c   # 4ac sur la pile 
    fsubp   # b2 - 4ac sur la pile 
ret 

來自Google我被引導認爲我應該在浮點堆棧的頂部留下一個浮點結果,但這不起作用,並且在C調用程序中打印的結果總是0.0000000。

我必須錯過一個非常小的東西,但沒有任何數量的谷歌搜索帶來了它,任何人都可以指向正確的方向嗎? 感謝您的關注。

回答

4

它確實對我有效。確保你沒有意外使用64位模式,因爲調用約定在那裏不同。也就是說,使用gcc -g -m32 foo.c bar.s進行編譯。

這就是說,我也看到了一些應該修復的潛在問題。

  • 由於您的全局變量是在C代碼中定義的,因此您不應該在程序集中使用.globl。如果有的話,你應該使用.extern,但是GAS並不要求這樣做。
  • 您不應該依賴默認操作數大小。如果有內存操作數,則應明確使用s後綴用於浮點數,l後綴用於雙精度值。例如,flds b以確保它作爲浮動裝載。
  • 您應該使用fsubrp,因爲堆棧的頂部是您的4ac,所以您使用fsubp計算的是4ac-b^2
+0

謝謝,m32選項是我錯過的,現在我將以一種不那麼緊張的方式閱讀其餘的有用評論。非常感謝你。 – pouzzler 2014-10-20 14:15:22

+0

如果你使用'as'來組裝,相應的標誌是'--32',如命令'as --32 -o delta.o delta.s' – Edward 2014-10-20 14:28:33