2014-10-20 53 views
4

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

但是,我希望个人学习稍微超出责任范围,创建一个返回浮点而不是整数的可用函数。

我想出了这个C(dont't介意全局,下一个练习的目的是有参数的适当功能):

# 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 

来自Google我被引导认为我应该在浮点堆栈的顶部留下一个浮点结果,但这不起作用,并且在C调用程序中打印的结果总是0.0000000。

我必须错过一个非常小的东西,但没有任何数量的谷歌搜索带来了它,任何人都可以指向正确的方向吗? 感谢您的关注。

回答

4

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

这就是说,我也看到了一些应该修复的潜在问题。

  • 由于您的全局变量是在C代码中定义的,因此您不应该在程序集中使用.globl。如果有的话,你应该使用.extern,但是GAS并不要求这样做。
  • 您不应该依赖默认操作数大小。如果有内存操作数,则应明确使用s后缀用于浮点数,l后缀用于双精度值。例如,flds b以确保它作为浮动装载。
  • 您应该使用fsubrp,因为堆栈的顶部是您的4ac,所以您使用fsubp计算的是4ac-b^2
+0

谢谢,m32选项是我错过的,现在我将以一种不那么紧张的方式阅读其余的有用评论。非常感谢你。 – pouzzler 2014-10-20 14:15:22

+0

如果你使用'as'来组装,相应的标志是'--32',如命令'as --32 -o delta.o delta.s' – Edward 2014-10-20 14:28:33