调用函数与浮子组件86的x87(call function with float in assemb

2019-10-23 04:08发布

我是新来的汇编编程,并作为一个更大的计划我需要传递浮点值到其他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"

86,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

我想,那里有一个问题,我只推32位时ext_funct预期的两倍。 但我试图FLD1启动,FLD1,fildl,FLD1启动12和16(%EBP),以及一些其他的为“好玩”。

  • 我的第一个问题是,缺少ext_func浮动堆栈(ST)的一些数据,因此是不能够使浮点值?(我知道你没有被调用函数,但事情的功能是什么犯规?)
  • 其次,该编译器永诺去到F-堆栈获得浮点值,如果它希望它们呢,还是可以从memorystack读?
  • 第三,还有其他seomething我在这里失踪? 如果我
printf("%f", a);     //3.140000  
printf("%f", str);      //3.140000

但另一种方式a给出了000000结束大是负面的数量(100位左右)。

Answer 1:

32位的惯例使用CPU堆栈来传递浮点参数。 它只使用FPU堆栈恢复它们。 是的,你应该将32位浮点转换为64位双,按照您提供的原型。

需要注意的是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


文章来源: call function with float in assembly x86 x87