如何使用内联汇编指定直接浮点数?
当我尝试编译此代码时:
#include main(int argc, char *argv[]) { double y = 0; __asm__ ("fldl $150;" "fsqrt;" "fstl %0;" : : "g" (y) ); printf("%f\n", y); return 0; }
我收到此错误:
sqrt.c: Assembler messages: sqrt.c:6: Error: suffix or operands invalid for `fld'
为什么这不起作用? 为什么我不能将数字“150”推入堆栈进行浮点运算?
我不知道支持立即使用的文字浮点常量的汇编语言。 通常的方法是声明包含浮点常量的初始化存储并引用它:
const1: dq 1.2345 ... fldl const1
对于您提供的示例,可以更直接地执行此操作:
printf ("%f\n", sqrt (150));
否则,这必须是一个人为复杂的项目,也许是家庭作业。
尝试这样的事情
push $0x???????? push $0x???????? fldl (%esp) addl $8,%esp
其中???????被替换为双常数的IEEE表示。 该方法的优点在于它在正常和位置无关(PIC,即共享库)代码中同样有效。
fld
指令的唯一有效操作数是存储器或浮点堆栈寄存器。
(另外,你已经指定了y
作为asm
块的输入操作数,而它应该是一个输出。可能更安全地将其限制为内存( "m"
,而不是"g"
)。)
如果你真的想用内联汇编这样做:
#include int main(void) { double y; const double k = 150.0; __asm__ ("fldl %1;" "fsqrt;" "fstl %0;" : "=m" (y) : "m" (k) ); printf("%f\n", y); return 0; }
aarch64支持它
#include #include int main(void) { register double d0 __asm__ ("d0"); __asm__ ("fmov d0, #1.5" : : : "%d0"); assert(d0 == 1.5); __asm__ ( "fmov d1, #2.5;" "fadd d0, d0, d1" : : : "%d0", "%d1"); assert(d0 == 4.0); }
编译并运行:
aarch64-linux-gnu-gcc -static -std=gnu99 reg_var_float.c qemu-aarch64 ./a.out
它永远不会让我开心,GNU GAS如何为每个拱门提供微妙的不同语法。
在Ubuntu 18.04上测试过。 GitHub上游 。
通过让PHP为您预处理文字,您可以绕过许多拒绝支持浮点文字的汇编程序。 (rawSingleHex取自此处 )。 在完美的世界中,C预处理器就足够了,但目前还不是这样。
#include int main(int argc, char **argv) { float y = 0; __asm__ ("pushl $\n" "fsqrt\n" "fstl %0\n" : : "g" (y)); printf("%f\n", y); return 0; }
运行php生成c文件,并运行c编译器来编译你的程序:P