DOS/Windows 下的汇编语言代码都是 Intel 风格的。但在 Unix 和 Linux 系统中,更多采用的还是 AT&T 格式,两者在语法格式上有着很大的不同:(可以参考下面的网站)
http://www.ibm.com/developerworks/cn/linux/l-assembly/
intel 风格代码:
; hello.asmAT&T 风格代码:
section .data ; 数据段声明
msg db "Hello, world!", 0xA ; 要输出的字符串
len equ $ - msg ; 字串长度
section .text ; 代码段声明
global _start ; 指定入口函数
_start: ; 在屏幕上显示一个字符串
mov edx, len ; 参数三:字符串长度
mov ecx, msg ; 参数二:要显示的字符串
mov ebx, 1 ; 参数一:文件描述符(stdout)
mov eax, 4 ; 系统调用号(sys_write)
int 0x80 ; 调用内核功能
; 退出程序
mov ebx, 0 ; 参数一:退出代码
mov eax, 1 ; 系统调用号(sys_exit)
int 0x80 ; 调用内核功能
#hell.s汇编器:
.data # 数据段声明
msg : .string "Hello, world!\\n" # 要输出的字符串
len = . - msg # 字串长度
.text # 代码段声明
.global _start # 指定入口函数
_start: # 在屏幕上显示一个字符串
movl $len, %edx # 参数三:字符串长度
movl $msg, %ecx # 参数二:要显示的字符串
movl $1, %ebx # 参数一:文件描述符(stdout)
movl $4, %eax # 系统调用号(sys_write)
int $0x80 # 调用内核功能
# 退出程序
movl $0,%ebx # 参数一:退出代码
movl $1,%eax # 系统调用号(sys_exit)
int $0x80 # 调用内核功能
AT&T风格代码用gas:它是 GCC 所依赖的后台汇编工具,通常包含在 binutils 软件包中。GAS 使用标准的 AT&T 汇编语法
eagle@eagle-QJC4:~/workspace/assembly$ as -o hell.o hell.s -g
intel风格代码用nasm:
eagle@eagle-QJC4:~/workspace/assembly$ nasm -f elf64 hello.asm -g
* bin flat-form binary files (e.g. DOS .COM, .SYS) aout Linux a.out object files aoutb NetBSD/FreeBSD a.out object files coff COFF (i386) object files (e.g. DJGPP for DOS) elf32 ELF32 (i386) object files (e.g. Linux) elf ELF (short name for ELF32) elf64 ELF64 (x86_64) object files (e.g. Linux) as86 Linux as86 (bin86 version 0.3) object files obj MS-DOS 16-bit/32-bit OMF object files win32 Microsoft Win32 (i386) object files win64 Microsoft Win64 (x86-64) object files rdf Relocatable Dynamic Object File Format v2.0 ieee IEEE-695 (LADsoft variant) object file format macho NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
链接器:
eagle@eagle-QJC4:~/workspace/assembly$ ld -o hello hello.o -g
调试器:
Linux 下调试汇编代码既可以用 GDB、DDD 这类通用的调试器,也可以使用专门用来调试汇编代码的 ALD(Assembly Language Debugger)。
从调试的角度来看,使用 GAS 的好处是可以在生成的目标代码中包含符号表(symbol table),这样就可以使用 GDB 和 DDD 来进行源码级的调试了。要在生成的可执行程序中包含符号表,可以采用下面的方式进行编译和链接:
<span style="font-size:18px;">eagle@eagle-QJC4:~/workspace/assembly$<span style="font-family: Arial, Helvetica, sans-serif;">as --gstabs -o hell.o hell.s</span></span><span style="font-size:18px;">eagle@eagle-QJC4:~/workspace/assembly$<span style="font-family: Arial, Helvetica, sans-serif;">ld -o hell hell.o</span></span>
执行 as 命令时带上参数 --gstabs 可以告诉汇编器在生成的目标代码中加上符号表,同时需要注意的是,在用 ld 命令进行链接时不要加上 -s 参数,否则目标代码中的符号表在链接时将被删去。
在 GDB 和 DDD 中调试汇编代码和调试 C 语言代码是一样的
下图为gdb调试: