簡體   English   中英

在程序集x86 x87中具有浮點數的調用函數

[英]call function with float in assembly x86 x87

我是匯編編程的新手,作為一個較大程序的一部分,我需要將浮點值傳遞給另一個C函數。 我有一個從測試程序到匯編函數的調用,該調用僅將參數壓入正確的堆棧,並調用第二個C函數。

我的C測試功能:

 extern void ext_func(char *result, double d); // C function
 extern double tester(char *str, float d);

 double a = tester(str, 3.14)
 printf("%s\n", str);       // Resulting in '0.000000'

 // doing some fancy stuff with the float value and puts in result
 ext_func(str, 3.14);       // gives str = "3.140000"

x86,gcc -m32:

     .globl tester
tester:
     pushl  %ebp        # Standard
     movl   %esp, %ebp  #
     flds   12(%ebp)    # Push second parameter on stack
     pushl  8(%ebp)
     call   ext_func
     addl   $4, %esp
     leave
     ret

我認為ext_funct期望double時,我只能推送32位。 但是我嘗試了fldl,fld1,fildl,fldl 12和16(%ebp),還有一些用於“樂趣”。

  • 我的第一個問題是,ext_func是否在float堆棧(ST)上丟失了一些數據,因此無法生成float值?(我知道您沒有被調用方函數,但該函數做什么無關緊要?)
  • 其次,如果編譯器期望浮動值,則是否始終轉到f堆棧以獲取浮點值,還是有可能從內存堆棧中讀取它們?
  • 第三,這里還有我想念的東西嗎? 如果我
printf("%f", a);     //3.140000  
printf("%f", str);      //3.140000

但是另一種方法則給出a大的負數(100位數左右),以000000結尾。

32位約定使用cpu堆棧傳遞浮點參數。 它僅使用fpu堆棧來返回它們。 是的,您應該根據提供的原型將32位浮點數轉換為64位double。

請注意, ext_funcvoid ,即它不返回任何內容,但是您將tester聲明為返回double ……不清楚要返回的內容,我假設您想要返回原始d (無論出於何種原因)。

因此,可能的實現方式可能是:

     .globl tester
tester:
     subl   $12, %esp      # allocate space for outgoing arguments
     movl   16(%esp), %eax # fetch our first argument (str)
     movl   %eax, (%esp)   # store as first outgoing argument
     flds   20(%esp)       # Fetch our second argument as float
     fstpl  4(%esp)        # store it as second outgoing argument as double
     call   ext_func
     flds   20(%esp)       # load d as return value
     addl   $12, %esp      # cleanup stack
     ret

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM