|
|
GAS(GNU as)汇编初学者入门笔记:从环境搭建到第一个程序
最近在折腾复古系统编程,发现GNU Assembler (GAS)是个很有意思的工具,整理了一下入门笔记分享给同样初学的朋友。
一、什么是GAS?
GAS 是 GNU 项目的汇编器,它支持多种架构(x86、ARM、RISC-V等),是 GCC 工具链的核心组件之一。和大家熟悉的 NASM/MASM 不同,GAS 使用 AT&T 语法,风格上有一些差异。
二、环境搭建
- # Debian/Ubuntu 安装
- sudo apt install binutils
- # 验证安装
- as --version
复制代码
在 DOS 复古环境下,可以用 DJGPP 工具链,它自带 GAS 的 DOS 移植版,适合在真机器上跑 32 位保护模式程序。
三、AT&T语法 vs Intel语法
刚从 NASM 转过来的朋友最容易混淆的就是语法差异:
| 对比项 | AT&T (GAS) | Intel (NASM) | | 源/目标顺序 | movl %eax, %ebx | mov ebx, eax | | 寄存器前缀 | %eax | eax | | 立即数前缀 | $0x10 | 0x10 | | 操作数长度 | movl (l=32位) | dword ptr |
四、第一个程序:Hello World
新建 hello.s:
- .data
- msg:
- .ascii "Hello, GAS!
- "
- len = . - msg
- .text
- .global _start
- _start:
- # write(1, msg, len)
- movl $4, %eax # sys_write
- movl $1, %ebx # fd = stdout
- movl $msg, %ecx # buffer
- movl $len, %edx # length
- int $0x80
- # exit(0)
- movl $1, %eax # sys_exit
- movl $0, %ebx # return 0
- int $0x80
复制代码
编译运行:
- as --32 -o hello.o hello.s
- ld -m elf_i386 -o hello hello.o
- ./hello
复制代码
五、初学者常见坑
- 忘记操作数长度后缀(.l/.b/.w)导致汇编错误
- 寄存器和立即数忘记加 % 和 $ 前缀
- 伪指令以点开头(.data/.text/.global),别和指令搞混
- int 0x80 调用号和参数顺序容易记错
六、调试技巧
用 gdb 调试汇编程序非常方便:
- gdb ./hello
- break _start
- run
- stepi # 单步执行
- info registers
复制代码
共勉,欢迎大佬补充指正! |
|