我正在尝试在 .c 文件中的汇编代码中编写二次根函数,但在正确获取 AT&T 格式的语法时遇到了问题。我得到的错误是:“在函数二次根中,未定义命名操作数 EAX,未定义命名操作数 1,asm 中未知寄存器名称 ST1”。任何帮助表示赞赏。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// function for checking that assembly code is computing the correct result
double quadraticRootC(double a, double b, double c)
{
return (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
}
double quadraticRoot(double a, double b, double c)
{
// assembly code to calculate the quadratic root
double root1;
asm(
//"quadraticRoot: "
//"enter 0,0 "
"fld %[a] \n" // a
"fadd %%ST \n" // 2a
"fld %[a] \n" // a, 2a
"fld %[c] \n" // c,a,2a
"fmulp %%ST(1) \n" // ac, 2a
"fadd %%ST \n" // 2ac, 2a
"fadd %%ST \n" // 4ac, 2a
"fchs \n" // -4ac, 2a
"fld \n" // b, -4ac, 2a
"fld %[b] \n" // b, b, -4ac, 2a
"fmulp %%ST(1) \n" // b*b, -4ac, 2a
"faddp %%ST(1) \n" // b*b-4ac, 2a
"ftst \n" // compare (b*b-4ac) with 0
"fstsw %%AX \n" // store status word in AX
"sahf \n"
"jb no_real_roots \n"
"fsqrt \n" // sqrt(b*b-4ac), 2a
"fld %[b] \n" // b, sqrt(b*b-4ac), 2a
"fchs \n" // -b, sqrt(b*b-4ac), 2a
"fadd %%ST(1) \n" // -b+sqrt(b*b-4ac), sqrt(b*b-4ac), 2a
"fdiv %%ST(2) \n" // -b+sqrt(b*b-4ac)/2a, sqrt(b*b-4ac), 2a
"mov %%EAX, %[root1] \n"
"fstp %%qword, %[EAX] \n" // store root1
//"fchs \n" // -sqrt(b*b-4ac), 2a
//"fld $b \n" // b, sqrt(b*b-4ac), 2a
//"fsubp %ST1 \n" // -b-sqrt(b*b-4ac), 2a
//"fdivrp %ST1 \n" // -b-sqrt(b*b-4ac)/2a
//"mov %EAX, (root2) \n"
//"fstp %qword[EAX] \n" // store root2
"mov %%EAX, %[1] \n" // real roots exist
"jmp short done \n"
"no_real_roots: \n"
"sub %%EAX, %%EAX \n" // EAX = 0 (no real roots)
"done: \n"
:"=m" (root1)
:[a] "m" (a), [b] "m" (b), [c] "m" (c), [root1] "m" (root1)
:"ST(1)"
//return(root1);
// done:
//"leave\n"
//"ret\n"
);
return(root1);
}
// main
int main (int argc, char **argv)
{
double a, b, c;
double root, rootC;
printf("*\n");
if (argc != 4) {
printf("need 3 arguments: a, b, c\n");
return -1;
}
a = atof(argv[1]);
b = atof(argv[2]);
c = atof(argv[3]);
root = quadraticRoot(a, b, c);
rootC = quadraticRootC(a, b, c);
printf("quadraticRoot(%.3f, %.3f, %.3f) = %.3f, %.3f\n", a, b, c, root, rootC);
return 0;
}
最佳答案
汇编代码可以从《Linux 中的汇编语言编程》第 456 页开始找到。 [参见:http://www.slideshare.net/guestacf37f1/guide-to-assembly-language-programming-in-linux]
问题是此代码不适合“剪切并粘贴”到 gcc '内联汇编'函数'asm()'中。
有关 gcc 内联汇编的示例,请参阅第 458 页函数“array_fsum()”中的示例。具体来说,请注意参数如何传递给内联汇编代码:
double array_fsum(double *value, int size)
{
double sum;
asm(" fldz; "
"add_loop: jecxz done; "
" decl %%ecx; "
" fadd1 (%%ebx, %%ecx,8); "
" jmp add_loop; "
"done: "
:"=t"*(sum) /* output */
:"b"(value), "c"(size) /* inputs */
:"cc");
return(sum);
}
gcc 内联汇编不需要 "%define a qword[EBP+8]\n"'enter'、'leave' 等。输入、输出和破坏的寄存器在最后三行中关联。
因此,问题中指示的代码旨在由汇编程序汇编为目标文件。
关于c - C 函数中的汇编代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23587840/