You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86_64汇编调用brk分配堆内存写入0x999以上地址触发段错误如何解决

问题原因
  • 核心错误是堆地址取值逻辑错误:heapStart是你在.data段定义的8字节变量,作用是存储brk返回的堆内存起始地址。但你代码中执行mov rdi, heapStart时,是把heapStart变量自身的虚拟地址(属于数据段地址范围)赋值给了rdi,而非取出该变量中存储的堆内存起始地址。你后续基于数据段地址做0x1000偏移写入,已经超出了数据段的合法映射范围,因此触发SIGSEGV段错误。
  • 你调用brk申请0x4000字节堆内存的逻辑本身没有问题,错误完全来自地址取值环节。
修复方案

将代码中mov rdi, heapStart修改为mov rdi, [heapStart]即可:方括号在NASM语法中表示取地址对应存储的内容,这行修改后你拿到的就是真正的堆内存起始地址,后续基于该地址的偏移写入都会落在你申请的合法堆内存区间内。

修复后的完整可运行代码如下:

global _start

section .data
    heapStart: dq 0 ; 存储堆起始地址

section .text
_start:
    mov rax, 12 ; brk系统调用号
    mov rdi, 0
    syscall ; 获取当前堆顶作为堆起始地址

    mov QWORD [heapStart], rax ; 保存堆起始地址

    lea rdi, [rax + 0x4000]
    mov rax, 12
    syscall ; 抬高堆顶0x4000字节,完成内存申请

    mov rdi, [heapStart] ; 取出堆起始地址,修复点

    mov BYTE [rdi + 0x1000], 'b' ; 写入合法堆地址,无段错误
    
    mov rax, 60 ; exit系统调用
    mov rdi, 0 ; 退出码
    syscall

内容的提问来源于stack exchange,提问作者Ari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:00:01