X86彙編AT&T語法基礎

x86架構彙編指令一般有兩種格式:Intel彙編和AT&T彙編,DOS、Windows使用Intel彙編,而Unix、Linux、MacOS使用AT&T彙編。

1.彙編組成

彙編程序是由定義好的段組成的,每個段的意義都不一樣。最常用的由以下幾個段:

  • data段:存放大部分的數據
  • bss段:存放未初始化的數據
  • rodata段:存放只讀的數據
  • text段:存放代碼
    對於最簡單一個程序而言,text段是必須的,其他都是可選的。

操作碼:但是操作碼都是一堆16進制字符,不太人性化,所以就就產生了助記符來方便程序員來編寫彙編代碼。
寄存器:x86_64 平臺16個通用寄存器和6個16位段寄存器
立即數:x86_64 平臺規定立即數的最大值不能超過32位。

大小寫:指令不區分大小寫,但是Intel格式的指令習慣上使用大寫字母,而AT&T格式習慣上使用小寫字母。

2.數據格式

GAS中每個操作都是有一個字符的後綴,表明操作數的大小。"b"表示 byte(一個字節) ;"w"表示 word(2 個字節) ;"l"表示 long(4 個字節) 。INTEL 中處理內存操作數時也有類似的語法如:BYTE PTR、WORD PTR、DWORD PTR。

C聲明 GAS後綴 大小(字節)
char b 1
short w 2
long l 4

注意:GAL使用後綴"l"同時表示4字節整數和8字節雙精度浮點數,這不會產生歧義因爲浮點數使用的是完全不同的指令和寄存器。

3.彙編指令格式

  1. 數據傳送
    movl %ebx,%eax      #寄存器前加%
    movl $1,%eax        #立即數前加$

    傳送方向與Intel格式相反,如:把EAX值存入EBX

    intel格式:MOV EBA, EAX
    at&t格式:movl %eax, %ebx

2.跳轉指令

lcall $secion:$offset
ljmp $secion:$offset
lret $stack_adjust 

4.尋址方式

  1. 直接尋址

    movl 0x8000, %eax  # 把地址0x8000上的值放到eax中
  2. 寄存器尋址

    movl $2, %ebx   # 立即數尋址
  3. 立即數尋址

    movl $2, %ebx  # 把2放到寄存器ebx中
  4. 間接尋址

    movl $0x8000, %ebx   # 立即數尋址
    movl %ebx, %eax  # 間址尋址, 把地址0x8000(放在寄存器ebx中)上的值放到eax
  5. 基址尋址

    movl $0x8000, %eax   # 立即數尋址
    movl 4(%eax), %ebx  #基址尋址, 把地址0x8004(0x8000+4)上的值放到eax中
  6. 變址尋址

    movl $0x8000, %eax   # 立即數尋址
    movl $0x4, %ebx   # 立即數尋址
    movl (%eax,%ebx), %ecx   #變址尋址, 把地址0x8004(0x8000+4)上的值放到ecx中
    movl  4(%eax,%ebx), %ecx   #變址尋址, 把地址0x8008(0x8000+4+4)上的值放到ecx中
  7. 比例變址尋址
    movl $0x2000, %eax   # 立即數尋址
    movl $0x2, %ebx   # 立即數尋址
    movl (,%eax,4), %ecx   #比例變址尋址, 把地址0x8000(0x2000 *4)上的值放到ecx中
    movl  6(,%eax,4), %ecx   #比例變址尋址, 把地址0x8006(0x2000 *4+6)上的值放到ecx中
    movl  (%ebx,%eax,4), %ecx   #變址尋址, 把地址0x8002(0x2000*4+2)上的值放到ecx中
    movl  6(%ebx,%eax,4), %ecx   #變址尋址, 把地址0x8008(0x2000*4+2+6)上的值放到ecx中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章