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

为何访问16位寄存器存储的值触发段错误,32位寄存器却正常?

问题分析与解决:x86-64下16位寄存器寻址触发段错误

核心原因:x86-64地址模式与16位寻址的冲突

在x86-64架构的Linux用户态环境中,程序默认运行在64位地址模式。当你使用16位寄存器(如si、bp)进行内存寻址时,CPU会强制切换到16位地址规则:

  • 16位模式下,内存地址由段寄存器值<<4 + 偏移量计算,最大寻址范围仅64KB
  • 现代Linux程序的代码段、数据段、栈段都映射在远大于64KB的高位地址空间,用16位寄存器计算出的地址必然无效,直接触发段错误。

而改用32位寄存器(如esi、ebp)或64位寄存器(如rbp)时,CPU会按32/64位地址模式处理,能正确访问程序的合法内存空间,因此不会出错。

代码修正方案

第一段数组操作代码

原问题:si是16位寄存器,无法存储现代程序中超过64KB的数组地址,寻址时直接越界。
修正:使用32位/64位寄存器存储地址:

myArray db 1,2,3,4; 已在正确段声明
;-----------------
mov esi, myArray  ; 用32位寄存器存储数组地址
mov ax, [esi]     ; 正常访问内存
sub ax, [esi+1]
mov [esi+3], ax

第二段栈操作代码

原问题:bp是16位寄存器,ss:[bp]会按16位栈地址规则寻址,而x86-64的栈是64位宽,栈地址远超出16位范围。
修正:使用64位寄存器rbp:

mov dx, 1234h
push dx
mov dx, 0ABCDh
push dx
mov rbp, rsp  ; 用64位寄存器指向栈顶
mov ax, ss:[rbp]

关于“语法错误”的说明

你的代码语法本身没有问题,但不符合x86-64默认地址模式的运行规则。16位寄存器寻址仅在x86-64的16位兼容模式下有效,而现代Linux用户态程序默认运行在64位模式,因此这种写法会导致非法内存访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 06:22:38