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中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章