c - C 函数中的汇编代码

标签 c gcc assembly gdb

我正在尝试在 .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/

相关文章:

c - 如何在 ELF 文件中查找变量类型?

c - 当计算结果为 0 的整数枚举用作指针时,gcc 是否应该发出警告?

windows - 我的 gcc.exe 在哪里?

c++ - Microsoft Detours - 无法 Hook __thiscall 函数

c - 访问没有结构名称的结构

c++ - 用于位置搜索的 C/C++ 库

汇编编号转为 ascii

c - 汇编 EAX 寄存器无故重置

C 线性搜索无法使用 strcmp 比较两个字符串,编译正常

gcc - 由GCC创建的exe文件没有权限?