第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指令使用數字型的标簽,以便可以在程式中多次使用宏函數而不會出現重複的彙編标簽。