当前位置: 首页 > news >正文

x64汇编之从程序编辑到系统调用

大家好,你们可以叫我凌,是个16岁的网络安全学习者。

今天我们来学习x64汇编的调试、结构以及系统调用,内容重要且基础。那我们就直接开始吧!

注:本教程采用使用范围更广的NASM语法,如需学习其他语法自行上网查找两种语法的区别即可。只因语法不同,因此花几十分钟即可快速掌握。


你的首个asm程序

按照各个语言的传统,我们先来简单写段“hello word”的程序,该文章也会从这个程序下手进行讲解,以帮助读者更好地了解。

打开终端,输入以下命令以此来创建并编写汇编程序(如不理解或许应该去补充下Linux的知识)

vim hello.asm

section .data msg db "hello, world",0 section .bss section .text global main main: mov rax, 1 ; 1表示写入 mov rdi, 1 ; 1表示标准输出 mov rsi, msg ; 需要显示的是字符串存放在rsi中 mov rdx, 12 ; 字符串的长度,不包括0 syscall ; 显示字符串 mov rax, 60 ; 60表示退出 mov rdi, 0 ; 0是成功退出代码 syscall ; 退出

随后点击Esc,输入:wq保存并退出编辑模式

这就是串简单的汇编代码,接下来我们要对其进行汇编和使用gcc链接达到运行的效果

汇编

汇编就是生成目标文件,使用以下命令来执行

各个部分解释如下

nasm
调用 NASM(Netwide Assembler)汇编器。

-f elf64
指定输出文件的格式elf64,即 64 位的 ELF(Executable and Linkable Format)。这是 Linux 系统上常用的目标文件格式,用于后续链接生成可执行文件。

hello.asm
输入的汇编源文件(通常包含 64 位 x86 汇编代码)。

-o hello.o
指定输出的目标文件名为hello.o。如果不加-o,默认输出文件名会是hello.o

这样 home目录下就会多出相关的文件(刚刚生成的)

使用gcc链接

这是是在Linux下使用GCC将之前生成的hello.o目标文件链接成最终的可执行文件hello

这里要注意-no-pie选项,这样就可以生成可执行文件了

以下为各部分解释

gcc
调用 GCC 编译器驱动,这里主要用于链接阶段(因为输入是.o目标文件)。

-no-pie

现代 Linux 默认生成PIE(位置无关可执行文件),程序加载地址随机化,安全性更高。

-no-pie后,程序会被链接到固定基址(如0x400000),代码中可以直接使用绝对地址。

hello.o
输入的目标文件,由之前的nasm -f elf64 hello.asm -o hello.o生成。

-o hello
指定输出的可执行文件名为hello(默认是a.out)。

注:是 GCC 链接时的一个选项,作用是生成传统、非位置无关的可执行文件。当手写汇编代码(如 NASM)没有使用RIP 相对寻址,而是直接写了绝对地址或依赖固定内存布局时用默认 PIE 模式链接会出错,此时加上-no-pie可以解决兼容性问题。这里进行了解即可

运行代码

接下来我们使用以下命令即可运行我们刚刚创建的可执行文件


汇编程序的结构

刚刚程序我们已经见识的汇编程序的模样,以下为汇编程序的主要组成部分:

.data段 .bss段 .text段

接下来我们将逐一讲解各个部分

.data段

.data段(section)就是准备好要处理的数据,使用以下格式声明和定义初始化数据

<变量名称> <类型> <值>

如该段包含变量,当源代码被汇编并链接到可执行文件时,将为该变量分配内存。变量名称为符号名称,对内存位置和变量的引用可以占用一个或多个内存位置。变量名称是指变量在内存中的起始位置

在上面程序中.data段包含变量msg,这是个符号名称,指向内存地址h,为字符串“hello word”的第一个字节。字符串是内存中字符的“列表”或“数组”

事实上,内存中的任何连续列表都可以视为字符串

另外,我们发现这后面有个0。你可以忽略或不写他,但是带来的后果得自负。这里的0并不是ASCII里面的0,而是单纯的数字0(添加一个空字节),并且它的位置包含一个字节

此外,该段还可以包含常量,学过其他语言的应该知道,即无法更改的值,下面为声明格式

<常量名称> equ <值>

例如:abc equ 12345

.bss段

.bss段就是写出处理数据的步骤。用于存放未初始化的量,未初始化变量的空间在此段声明

<变量名称> <类型> <数字>

以下为bss段的数据类型

例如以下内容声明个包含20个双字的数组

dArray resd 20

该段的变量不包含任何值,这些值将在执行中分配。内存位置不是在编译时保留的,而是在执行时保留的。

当程序开始执行时,程序会从操作系统中请求所需的内存,分配给.bss段中变量并初始化为零。如果执行时没有足够的内存可用于.bss变量,程序将崩溃

.txt段

.txt段是所有操作所在的位置

global main main:

main:称为标签,后面最好跟上冒号“:”避免引起不必要的麻烦

此外我们还会发现有许多数字,这称为系统调用码,不同数字在不同寄存器里面有不同的意思。比如下面这串代码就是写入的意思(有关寄存器的内容见x64汇编:内存工作的基本原理,之后会出更详细的寄存器文章)

mov rax,1

以下为mov的指令用法(极为重要!)

mov 寄存器,即时值

mov 寄存器,内存

mov 内存,寄存器

注:mov 内存,内存 为不合法的!


系统调用

什么是系统调用

我们的程序运行在“用户态”,不能直接操作硬件(如屏幕、键盘)。需要操作系统内核帮忙时,通过“系统调用”请求内核执行。syscall指令就是触发这个请求的开关。

系统调用的三个步骤

1.rax中放服务号(告诉内核做什么)
2.rdi, rsi, rdx, r10, r8, r9中放参数(告诉内核具体怎么做,最多6个)
3. 执行syscall

常用服务号(rax)

服务号名称功能
1sys_write写入数据(如输出到屏幕)
60sys_exit退出程序

参数寄存器

参数位置寄存器
第1个rdi
第2个rsi
第3个rdx
第4个r10
第5个r8
第6个r9

注:超过6个参数时通过栈传递,但入门极少遇到。

易混淆点澄清

1.rax=1“写入”服务;rdi=1sys_write中是“屏幕”,在sys_exit中是“退出码1(错误)”。同一个数字在不同寄存器/不同调用中含义不同。
2.只有sys_exitrdi才叫“退出码”;在sys_write中叫“文件描述符”

http://www.cnnetsun.cn/news/1810794.html

相关文章:

  • MySQL优化全攻略:索引、SQL与分库分表的最佳实践纠
  • Concept HDL高效网络名批量互换:基于脚本的Pin Swap自动化实现
  • Windows系统下Mamba-SSM避坑指南:从WSL配置到编译成功
  • 3分钟上手PVZ Toolkit:解锁植物大战僵尸无限潜能的专业修改器
  • 终极虚拟游戏控制器驱动:让你收藏的手柄重获新生
  • 图像梯度检测实战:Sobel、Scharr与Laplacian算子的性能对比与应用场景
  • LangGraph实战指南:从核心概念到复杂工作流构建
  • 别再让后端背锅了!前端独立搞定文件上传:华为云OBS + Vue/Element-UI保姆级配置
  • 别再手动传日志了!用Flume+Spark Streaming搭建实时数据管道(保姆级避坑指南)
  • 小马智行发布PonyWorld世界模型2.0,如何改变市场?
  • VMware Cloud Foundation 9.0 自动化实验室部署教程
  • 解锁游戏控制新维度:ViGEmBus虚拟手柄驱动深度解析
  • C# ASP.NET学生信息管理系统源代码,基于SQL Server实现学生管理、课程管理、成...
  • CHARLS认知数据修正实战:如何用教育程度调整不同波次测试分数(附Stata代码)
  • 缠论可视化插件:5分钟快速掌握通达信智能分析工具
  • Windows大数据开发环境搭建完整指南:使用winutils解决Hadoop兼容性问题
  • 如何用tiny11builder快速打造轻量级Windows 11系统:终极精简指南
  • 【2026 AI原生研发技术雷达图】:基于全球412家科技企业实测数据,定位你团队的技术坐标与升级路径
  • Unity 3D新手必看:5分钟掌握Scene窗口视角调整与Main Camera同步技巧
  • Phi-3-mini-4k-instruct-gguf入门指南:中文标点智能补全、引号嵌套处理与段落空行控制
  • 2026 云南 GEO 优化服务商深度测评:5 家实力对比
  • 海外项目实战:用uniapp搞定谷歌登录,绕过网络限制的纯前端方案(附完整代码)
  • ANOVA事后检验怎么选?Tukey-Kramer/Bonferroni/Scheffé全对比指南
  • 从电子琴到智能家居:无源蜂鸣器如何玩出花样?附ESP32播放《超级玛丽》主题曲代码
  • KMS_VL_ALL_AIO:如何在3分钟内智能激活Windows与Office?
  • 不符合国网“智能融合终端”2025新规?你的设备面临升级风险!
  • 终极指南:如何高效使用ControlNet-v1-1_fp16_safetensors实现精准图像控制
  • 别再傻傻等上传了!手把手教你利用阿里云盘‘秒传’特性高效备份常见软件与镜像
  • 百川2-13B-4bits量化版调优指南:降低OpenClaw任务失败率
  • ACadSharp完整指南:.NET平台CAD文件处理深度解析