【问题标题】:call function with float in assembly x86 x87在汇编 x86 x87 中调用带有浮点数的函数
【发布时间】:2015-07-31 01:37:18
【问题描述】:

我是汇编编程的新手,作为更大程序的一部分,我需要将浮点值传递给另一个 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 期待双倍时我只推 32 位存在问题。但我尝试了 fldl、fld1、fildl、fldl 12 和 16(%ebp),以及其他一些“乐趣”。

  • 我的第一个问题是,ext_func 是否缺少浮点堆栈 (ST) 上的一些数据,因此无法生成浮点值?(我知道你没有被调用函数,但函数的作用无关紧要? )
  • 其次,如果编译器需要浮点值,编译器是否总是转到 f 堆栈获取浮点值,或者是否可以从内存堆栈中读取它们?
  • 第三,这里还有什么我遗漏的吗?如果我
printf("%f", a);     //3.140000  
printf("%f", str);      //3.140000

但另一方面,a 给出了以 000000 结尾的大负数(100 位左右)。

【问题讨论】:

    标签: c assembly x86 stack x87


    【解决方案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
    

    【讨论】:

    • 这很有意义。在我的程序中,我实际上不想将浮点数作为第二个参数,而是像tester(char *str, ...) 这样的未定义参数。未定义的数字在入栈时总是加倍吗?
    • 是的,变量部分中的浮点参数默认提升为双精度值。当然,整数不是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多