第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指令使用数字型的标签,以便可以在程序中多次使用宏函数而不会出现重复的汇编标签。