DOS/Windows 下的汇编语言代码都是 Intel 风格的。但在 Unix 和 Linux 系统中,更多采用的还是 AT&T 格式,两者在语法格式上有着很大的不同:(可以参考下面的网站)
http://www.ibm.com/developerworks/cn/linux/l-assembly/
intel 风格代码:
; hello.asm 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 ; 调用内核功能AT&T 风格代码:
#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调试: