天天看點

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

繼續閱讀