linux下汇编学习笔记[第一天]

时间:2021-07-08 21:50:13

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调试:

linux下汇编学习笔记[第一天]