准备工作:安装必要工具
-
安装汇编器和链接器
使用GNU工具链(已预装于大多数Linux发行版):sudo apt install build-essential # Debian/Ubuntu sudo dnf install gcc binutils # Fedora/CentOS
验证安装:
as --version # 查看汇编器版本 ld --version # 查看链接器版本
-
选择文本编辑器
推荐轻量级工具:nano
、vim
或 VS Code。
编写第一个汇编程序(Hello World)
创建文件 hello.s
(AT&T语法):
.section .data msg: .asciz "Hello, Linux Assembly!\n" # 定义字符串 .section .text .globl _start # 声明入口点 _start: # 系统调用: write(1, msg, len) mov $1, %rax # syscall号: 1 (write) mov $1, %rdi # 文件描述符: stdout=1 lea msg(%rip), %rsi # 字符串地址 mov $23, %rdx # 字符串长度 syscall # 触发系统调用 # 系统调用: exit(0) mov $60, %rax # syscall号: 60 (exit) xor %rdi, %rdi # 退出码: 0 syscall
编译与链接
-
汇编生成目标文件
as -o hello.o hello.s
-
链接为可执行文件
ld -o hello hello.o
-
运行程序
./hello # 输出: Hello, Linux Assembly!
调试汇编代码(使用GDB)
-
编译时添加调试信息
as -g -o hello.o hello.s ld -o hello hello.o
-
启动GDB调试
gdb ./hello
-
常用调试命令
(gdb) break _start # 在入口点设断点 (gdb) run # 运行程序 (gdb) info registers # 查看寄存器值 (gdb) stepi # 单步执行一条指令 (gdb) x/s &msg # 检查字符串内容
进阶实践技巧
-
内联汇编(C语言中嵌入汇编)
#include <stdio.h> int main() { int a = 10, b; asm volatile ( "mov %1, %%eax;" "add $5, %%eax;" "mov %%eax, %0;" : "=r"(b) // 输出 : "r"(a) // 输入 : "%eax" // 破坏寄存器 ); printf("Result: %d\n", b); // 输出15 }
编译:
gcc -o inline inline.c
-
32位与64位代码区别
- 32位:使用
int $0x80
系统调用,寄存器命名(eax
,ebx
) - 64位:使用
syscall
,寄存器命名(rax
,rdi
) - 编译32位程序需安装兼容库:
sudo apt install gcc-multilib as --32 -o hello32.o hello.s ld -m elf_i386 -o hello32 hello32.o
- 32位:使用
常见问题解决
-
段错误(Segmentation Fault)
- 检查内存访问越界(如
mov
操作错误地址) - 用GDB的
backtrace
和x
命令分析崩溃点
- 检查内存访问越界(如
-
系统调用参数错误
- 查阅Linux系统调用表:
https://syscalls.w3challs.com/ - 确认寄存器传参顺序(64位:
rdi
,rsi
,rdx
)
- 查阅Linux系统调用表:
-
链接器报错
undefined reference to _start
:确保声明.globl _start
- 入口点错误:使用
gcc
链接时需用main
替代_start
学习资源推荐
- 官方文档
GNU Assembler Manual - 书籍
《Professional Assembly Language》(Richard Blum)
《x86-64 Assembly Language Programming with Ubuntu》(Ed Jorgensen) - 实践项目
- 用汇编实现冒泡排序
- 编写Shellcode并测试
- 修改内核系统调用
引用说明: 参考GNU汇编器官方文档、Linux内核系统调用表及《x86-64 Assembly Language Programming with Ubuntu》中的实践案例,系统调用号基于Linux 5.x内核,不同架构可能需调整寄存器使用。
通过本指南,您已掌握Linux下汇编编程的核心流程,持续实践是精通底层开发的关键——尝试反编译C程序、分析编译器生成的汇编代码,将大幅提升您的系统级编程能力。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/9271.html