AT&T语法和Intel语法x86汇编的区别

AT&T语法和Intel语法x86汇编的区别<转自 北风北的猪>

x86汇编一直存在两种不同的语法,intel语法和AT&T语法,在intel的官方文档中使用intel语法,Windows也使用intel语法,而UNIX平台的汇编器一直使用AT&T语法。

linux下,x86汇编AT&T语法用GAS编译,Intel语法用NASM编译。

AT&T和Intel语法没有好坏之分,只是语法有差异而已。

GAS的语法主要有

* 寄存器名前缀%

* 操作数是源在前,目的在后。与Intel语法刚好相反。

* 操作数长度在指令名后缀,b表示8位,w表示16位,l表示32位,如movl %ebx,%eax。

* 立即操作数(常量)用$标示,如addl $5,%eax

* 变量加不加$有区别。如movl $foo, %eax表示把foo变量地址放入寄存器%eax。movl foo,%eax表示把foo变量值放入寄存器%eax。

hello_world例子

NASM (hello.asm)

section .text    ;section declaration

   ;we must export the entry point to the ELF linker or
    global _start ;loader. They conventionally recognize _start as their
   ;entry point. Use ld -e foo to override the default.

_start:

;write our string to stdout

        mov     edx,len ;third argument: message length
        mov     ecx,msg ;second argument: pointer to message to write
        mov     ebx,1   ;first argument: file handle (stdout)
        mov     eax,4   ;system call number (sys_write)
        int     0x80 ;call kernel

;and exit

 mov ebx,0 ;first syscall argument: exit code
        mov     eax,1   ;system call number (sys_exit)
        int     0x80 ;call kernel

section .data    ;section declaration

msg     db      "Hello, world!",0xa ;our dear string
len     equ     $ - msg                 ;length of our dear string

GAS (hello.S)

.text     # section declaration

   # we must export the entry point to the ELF linker or
    .global _start # loader. They conventionally recognize _start as their
   # entry point. Use ld -e foo to override the default.

_start:

# write our string to stdout

 movl $len,%edx # third argument: message length
 movl $msg,%ecx # second argument: pointer to message to write
 movl $1,%ebx  # first argument: file handle (stdout)
 movl $4,%eax  # system call number (sys_write)
 int $0x80  # call kernel

# and exit

 movl $0,%ebx  # first argument: exit code
 movl $1,%eax  # system call number (sys_exit)
 int $0x80  # call kernel

.data     # section declaration

msg:
 .ascii "Hello, world!\n" # our dear string
 len = . - msg   # length of our dear string

Fornasmexample:

$ nasm -f elf hello.asm

Forgasexample:

$ as -o hello.o hello.S

This makeshello.oobject file.

Second step is producing executable file itself from the object file by invoking linker:

$ ld -s -o hello hello.o

看一些例子:

+-----------------------------------+---------------------------------------------+
|            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    |
+-----------------------------------+----------------------------------------------+
cmp    eax,ebx    ----    cmpl    %ebx,%eax
参考:

Linux Assembly HOWTO,3.2. GAS,   6.2. Hello, world!   

GCC-Inline-Assembly-HOWTO,3. GCC Assembler Syntax.   

这个gnu的as manual有更详细的说明,还有针对不同硬件的:

Using as,   9.13 80386 Dependent Features   

 


你可能感兴趣的:(其他)