gpt4 book ai didi

在程序集 x86 x87 中使用 float 调用函数

转载 作者:太空宇宙 更新时间:2023-11-04 02:42:36 26 4
gpt4 key购买 nike

我是汇编编程的新手,作为一个更大程序的一部分,我需要将浮点值传递给另一个 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-stack 获取它需要的 float 值,或者是否可以从 memorystack 中读取它们?
  • 第三,我还缺少其他什么东西吗?如果我
printf("%f", a);     //3.140000  
printf("%f", str); //3.140000

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

最佳答案

32 位约定使用 cpu 堆栈来传递浮点参数。它只使用 fpu 堆栈来返回它们。是的,您应该按照您提供的原型(prototype)将 32 位 float 转换为 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

关于在程序集 x86 x87 中使用 float 调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30322006/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com