2010-02-12 246 views
0

我在写一个名为absD的函数,它返回它的参数的绝对值。 我不想使用任何预定义的功能。现在,当我尝试编译它时,我得到一个解析错误。double的绝对值

我想要所有我必须做的事情来获得双倍的绝对值是改变符号位?这是我所

#include <stdio.h> 
#include <stdlib.h> 

#define PRECISION 3 

double absD (double n) 
{ 

asm(" fld  %eax \n" 
    " movl $0x7FFFFFFFFFFFFFFF, %eax \n"  
    " pop  %eax  \n" 

    ); 

return n; 


} 

int main (int argc, char **argv) 
{ 
double n = 0.0; 

printf("Absolute value\n"); 
if (argc > 1) 
    n = atof(argv[1]); 

printf("abs(%.*f) = %.*f\n", PRECISION, n, PRECISION, absD(n)); 

return 0; 
} 

我固定的花括号.. 我得到的错误是

~ $ gc a02 
gcc -Wall -g a02.c -o a02 
/tmp/ccl2H7rf.s: Assembler messages: 
/tmp/ccl2H7rf.s:228: Error: suffix or operands invalid for `fld' 
/tmp/ccl2H7rf.s:229: Error: missing or invalid immediate expression `0x7FFFFFFFF 
FFFFFFF' 
~ $ 
+1

什么是编译错误? – 2010-02-12 01:34:50

+0

而错误是...? – GManNickG 2010-02-12 01:35:05

+4

科里希望*你*编译它,并将错误报告给他,并在完成后打嗝。 – 2010-02-12 01:40:43

回答

1

你需要做的是在组装?这是一项家庭作业要求,还是你在寻找非常高的性能?

这不使用任何预定义的功能:

double absD(double n) 
{ 
    if (n < 0.0) 
     n = -n; 

    return n; 
} 
+2

return(n <0.0)? -n:n; – pm100 2010-02-12 02:06:10

+1

这是一项家庭作业。我需要在装配中这样做。我不想让别人为我做。我只需要一些指导 – Steller 2010-02-12 02:21:33

+2

' #define absD fabs' – kennytm 2010-02-12 19:56:01

1

我不是专家,但它看起来像你使用(打开的装配体块和}结束它。你可能应该使用一个或另一个,而不是不一致。

1
asm(" fld  %eax \n" 
" movl $0x7FFFFFFFFFFFFFFF, %eax \n"  
" pop  %eax  \n" 

}; 

注意分号前的曲线支架。

+0

嘿,我修复了大括号并发布了新的错误信息 – Steller 2010-02-12 02:08:40

1

取决于你想如何治疗-0.0,你可以使用C99/POSIX(2004)的signbit()函数。

#include <math.h> 

double absD (double x) 
{ 
    if (signbit(x)) { 
#ifdef NAIVE 
     return 0.0 - x; 
#else 
     return x &= 0x7FFFFFFFFFFFFFFF; 
#endif 
    } else { 
     return x; 
    } 
} 

但坦率地说,如果你使用标准C库(libc)ATOF和printf,我不明白为什么不使用fabs()是可取的。因为你也可以在C中进行正常的位操作。

当然,如果你正在使用程序集,为什么不使用fchs op呢?

+1

这是一项家庭作业。我需要在装配中这样做。我不想让别人为我做。我只需要一些指导就可以做什么。 – Steller 2010-02-12 02:22:18

+0

然后它应该被标记为HOMEWORK。 – mctylr 2010-02-12 02:43:17

1

你的汇编代码有错误,汇编代码给你完全合理的错误信息。

  • 您不能加载从%eax中浮点值直接 - 操作数必须是一个地址,从

  • 加载你不能有不适合在常量文本32位。

+0

那么我如何加载浮点? – Steller 2010-02-12 02:49:58

1

浮点数的符号只是高位,所以您只需清除最高位。

如果你必须在汇编中做到这一点,那么在我看来,你会更好地使用整数而不是浮点指令。您无法对浮点寄存器执行按位操作。如果处理器没有8字节的整型寄存器,那么不需要将整个8字节值加载到任何寄存器中,只需要在高字节(或整型)上操作即可。

0

/tmp/ccl2H7rf.s:228: Error: suffix or operands invalid for `fld'

fld需要操作数在内存中。把它放在内存中,即堆栈,并提供地址。

/tmp/ccl2H7rf.s:229: Error: missing or invalid immediate expression `0x7FFFFFFFF FFFFFFF'

EAX不能保存多于32位。如果你的意思是这是一个浮点数,用一条加载指令(即fld)将它放在浮点堆栈上。