GCC內聯彙編(1)Get started

 

GCC內聯彙編(1)Get started

  • 作者:柳大·Poechant(鍾超)
  • 郵箱:zhongchao.ustc#gmail.com(# -> @)
  • 博客:Blog.CSDN.net/Poechant
  • 日期:July 7th, 2012

1. Intel vs. AT&T

其實並不是要說 Intel 和 AT&T PK 的故事,哈哈。因爲首先要熟悉 Intel syntax 的彙編指令寫法和 AT&T syntax 彙編指令的寫法,所以看下錶:

 +------------------------------+------------------------------------+ |       Intel Code             |      AT&T Code                     | +------------------------------+------------------------------------+ | mov     eax,1                |  movl    $1,%eax                   |    | mov     ebx,0ffh             |  movl    $0xff,%ebx                |    | int     80h                  |  int     $0x80                     |    | mov     ebx, eax             |  movl    %eax, %ebx                | | mov     eax,[ecx]            |  movl    (%ecx),%eax               | | mov     eax,[ebx+3]          |  movl    3(%ebx),%eax              |  | mov     eax,[ebx+20h]        |  movl    0x20(%ebx),%eax           | | add     eax,[ebx+ecx*2h]     |  addl    (%ebx,%ecx,0x2),%eax      | | lea     eax,[ebx+ecx]        |  leal    (%ebx,%ecx),%eax          | | sub     eax,[ebx+ecx*4h-20h] |  subl    -0x20(%ebx,%ecx,0x4),%eax | +------------------------------+------------------------------------+ 

2. 示例

看一個用內聯彙編寫的例子,計算兩數的和:

 #include <stdio.h>                                                                                                                                                                                    int main(void) {      int foo = 10, bar = 15;      __asm__ __volatile__ (         "addl   %%ebx, %%eax"         :"=a"(foo)         :"a"(foo), "b"(bar)         :"%eax"     );      printf("foo + bar = %d\n", foo);      return 0; } 

該程序作如下解釋:

  • __asm__用於表示這是一個內聯彙編代碼段;
  • 如果使用了__volatile修飾符,則這段內聯彙編代碼不會被編譯器優化掉,但是如果只是做簡單的計算,不會產生任何可能的 side effects,則最好不要加這個修飾符,這樣可以使編譯器幫助我們優化代碼;
  • "=a"(foo)"表示這段內聯彙編代碼運行結束後,輸出結果放在寄存器%eax中,然後%eax中的內容再放到fooC變量中;
  • "a"(foo)表示這段內聯彙編代碼開始運行時,fooC變量輸入到%eax寄存器中,多個輸入值可以用上面示例中的方式表達。
  • 以冒號開始的那兩行,其實都是“約束”,這個是constraint的直譯,其實你可以理解爲邊界條件,即輸入輸出條件。
  • 最後一個冒號開始的行,是告訴編譯器,哪些寄存器的值會在內聯彙編代碼的運行過程中被篡改,因此不要使用這些寄存器去保存值。這裏就是%eax的值會被篡改的意思。

3. 寄存器縮寫

+---+--------------------+ | r |    Register(s)     | +---+--------------------+ | a |   %eax, %ax, %al   | | b |   %ebx, %bx, %bl   | | c |   %ecx, %cx, %cl   | | d |   %edx, %dx, %dl   | | S |   %esi, %si        | | D |   %edi, %di        | +---+--------------------+ 

Reference

  1. http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
  2.  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章