2011-05-28 260 views
3

我正在爲16位處理器,特別是8086/8088處理浮點計算器。 我使用的是as88 Tracker,它沒有實現浮點,不允許我在「%f」中使用sscanf。使用as88彙編器從彙編代碼調用C函數

我想過在C代碼中這樣做,並從我的彙編代碼中調用此函數,但無法找到如何去做。

這是到目前爲止我的代碼:

 
#include "../syscalnr.h" 

.sect .text 
_code_:  
     push bp 
     mov bp, sp 

     push SEGOP-PRIOP ! Pushes PRIOP String Size into the stack 
     push PRIOP  
     push STDOUT  
     push _WRITE   ! System Call to print string on the display 
     sys 

     add sp, 8 
     mov di, rasc ! Prepares DI to receive char 
     push _GETCHAR 
1:  sys 
     cmpb al, '\n' ! Compares with EOL and keeps storing the string chars 
     je 2f 
     stosb   ! Stores char into variable rasc 
     jmp 1b 

2:  xorb al, al  ! Clears registers 
     add sp, 2 

.sect .data 
_data_: 

PRIOP:  .asciz "Insert first operand:\n " 
SEGOP:  .ascii "Insert second operand: " 

FORMAT:  .asciz "%u" 
F_CHAR:  .asciz "%c" 
F_STR:  .asciz "%s\n" 

.sect .bss 
_bss_:   
rasc:  .space 10 

我希望能夠寫一個C函數爲:

float* getVal(char* ch) { 

    float fVal; 
    sscanf(ch, "%f", &fVal); 

    if(fVal == 0) return 0; 

    return fVal; 
} 

從我的彙編代碼中調用它翻譯的串號輸入由用戶變成浮動。

任何人都可以幫助我嗎?

謝謝!

+0

你想要的功能似乎是'strtod',它是標準庫的一部分。 – 2011-05-28 21:22:07

+0

似乎我也可以使用那個,但回到主要觀點,我怎樣才能從我的彙編代碼調用這個函數? – 2011-05-28 22:56:22

回答

0

有一種C語言函數調用約定,該函數調用約定指示在輸入函數時如何設置寄存器。你必須找出那個約定是什麼 - 也許通過查看一個C編譯的obj文件 - 然後讓你的asm代碼遵守它,就像你執行sys時一樣。不過,我認爲這不會是你唯一的問題,因爲sscanf()無疑會在C庫中調用大量其他函數,然後你需要找到它;並理解;並整合;和調試;並繼續。忘記那個噪音吧。

未經請求的建議警報:它可能更容易 - 如果我這樣做會更容易 - 只是在您的asm代碼中解析輸入。如果這個人打字「3.14159」很簡單,不是嗎?即使你看到科學記數法的輸入,這也不算太壞,imo。

+0

取決於您想要或需要的正確性水平。解析浮點而不捨入錯誤是一項艱鉅的任務,即使在高級語言中也是如此。我會非常害怕嘗試它。 – 2011-05-28 20:42:04

+0

這取決於。我需要符合IEEE 754-2008標準的浮點數。 因此,如果我有一個字符串「3.14159」我怎麼能解析它,我可以有一個標準化的二進制準備好被屏蔽爲符號,指數和分數,然後正確極化後驗計算? 簡而言之:我需要一個符合IEEE 754-2008標準的二進制文件,所以我可以在計算中使用它。如何將字符串「3.14159」轉換爲浮點數3.14159? – 2011-05-28 21:19:52

+0

我不理解你的問題。你有這個字符串恰好代表一個浮點數:「3.14159」。您必須將其解析爲整數部分和小數部分,然後將該吸盤轉換爲四字節的IEEE-754二進制文件。這當然不是微不足道的,但看起來很簡單,除了要求您瞭解IEEE-754之外。那麼我沒有得到你的問題的哪一部分? – 2011-06-01 03:57:37

0

首先,只有當您的C庫也在仿真器上運行時纔會起作用。 我不知道究竟是如何接近你的8088模擬器堅持在x86 ABI,但假定它沒有在過去的20年變化不大(咳嗽)從彙編程序調用C函數那樣:

push RETVAL ;last parameter first (address of float to return) 
    push STRFLOAT ;first parameter last (format string) 
    call sscanf ;error code is in ax 
    add  sp,4  ;returned float is at RETVAL 
    ;do something... 

.sect .data 
    STRFLOAT: .asciz "%f" 

.sect .bss 
    RETVAL: .space 4 

根據名稱的改變,您可能需要用_sscanfsscanf_替換sscanf