4

我们的课程练习要求我们在 GNU 汇编中创建一个 delta = b2 - 4ac 函数,并从 C 中访问它。由于这是一门关于编译器的课程,而不是关于汇编的课程,教授选择只演示整数功能,并期望一个整数功能。

但是,我希望个人学习能够超越职责范围,并创建一个返回浮点而不是整数的可用函数。

我想出了这个 C (不要介意全局变量,下一个练习的目的是使用带有参数的适当函数):

# include <stdio.h>

extern float delta();
float a, b, c;

int main() {
    a = 3;
    b = 5;
    c = 4;
    printf("δ = %f\n", delta());
    return 0;
}

还有这个 GNU GAS:

.globl a
.globl b
.globl c
.globl delta
.f4: .float 4.0     # constante 4

.text
delta:
    fld b           # b sur la pile
    fmul b          # b2 sur la pile
    fld .f4         # 4 sur la pile 
    fmul a          # 4a sur la pile
    fmul c          # 4ac sur la pile
    fsubp           # b2 - 4ac sur la pile
ret

谷歌让我相信我应该在浮点堆栈的顶部留下一个浮点结果,但这不起作用,并且在 C 调用程序中打印的结果总是 0.0000000。

我必须错过一个非常小的东西,但是没有多少谷歌搜索会带来它,有人能指出我正确的方向吗?感谢您的关注。

4

1 回答 1

3

它对我有用。确保您没有意外使用 64 位模式,因为那里的调用约定不同。也就是gcc -g -m32 foo.c bar.s用来编译。

也就是说,我也看到了一些应该解决的潜在问题。

  • 由于您的全局变量是在 C 代码中定义的,因此不应.globl在程序集中使用。如果有的话,你应该使用.extern,但 GAS 不需要。
  • 您不应依赖默认操作数大小。当您有内存操作数时,您应该明确使用s浮点数的后缀和双精度数的后缀。l例如,flds b要确保它作为浮点数加载。
  • 你应该使用fsubrp,因为堆栈的顶部是你的4ac,所以你计算使用fsubp的是4ac-b^2.
于 2014-10-20T14:04:13.507 回答