天天看点

第61部分- Linux x86 64位汇编内联汇编宏函数第61部分- Linux x86 64位汇编内联汇编宏函数

第61部分- Linux x86 64位汇编内联汇编宏函数

C程序中的任何位置都可以防止内联汇编代码,但是大多数程序员把内联汇编代码用作宏函数。

C宏函数

先回顾下C宏函数示例

#include <stdio.h>

#define SUM(a, b, result) \
            ((result) = (a) + (b))

int main()
{
   int data1 = 5, data2 = 10;
   int result;
   float fdata1 = 5.0, fdata2 = 10.0;
   float fresult;

   SUM(data1, data2, result);
   printf("The result is %d\n", result);
   SUM(1, 1, result);
   printf("The result is %d\n", result);
   SUM(fdata1, fdata2, fresult);
   printf("The floating result is %f\n", fresult);
   SUM(fdata1, fdata2, result);
   printf("The mixed result is %d\n", result);
   return 0;
}
           

gcc -o mactest1 mactest1.c

宏函数中定义的变量完全独立于程序中定义的结果变量。

之类的宏函数SUM()可以处理整数输入值、数字型输入值、浮点输入值,甚至还可以处理混合的输入值和输出值。

汇编宏函数

也可以声明包含内联汇编代码的宏函数。必须使用扩展asm格式,以便定义正确的输入值和输出值。

Asm语句必须括在一对花括号中,以便指出语句的开头和结尾。如果没有花括号,每次在C代码中使用宏时,编译器都会生成错误消息。

示例

#include <stdio.h>

#define GREATER(a, b, result) ({ \
    asm("cmp %1, %2\n\t" \
        "jge 0f\n\t" \
        "movl %1, %0\n\t" \
        "jmp 1f\n\t" \
        "0:\n\t" \
        "movl %2, %0\n\t" \
        "1:" \
        :"=r"(result) \
        :"r"(a), "r"(b)); })

int main()
{
   int data1 = 10;
   int data2 = 20;
   int result;

   GREATER(data1, data2, result);
   printf("a = %d, b = %d    result: %d\n", data1, data2, result);

   data1 = 30;
   GREATER(data1, data2, result);
   printf("a = %d, b = %d    result: %d\n", data1, data2, result);
   return 0;
}
           

gcc -o mactest2 mactest2.c

可以成功运行。

输入变量a和b被赋值给寄存器,可以在CMP指令中使用它们。

JGE/JMP指令使用数字型的标签,以便可以在程序中多次使用宏函数而不会出现重复的汇编标签。

继续阅读