You need to enable JavaScript to run this app. x86汇编入门:数组索引使用异常触发code 10、signal 11报错的咨询
优惠活动
大模型
产品
解决方案
定价
更多

x86汇编入门:数组索引使用异常触发code 10、signal 11报错的咨询

汇编代码两类报错的根因与修正方案

两类报错的本质区别

  • signal 11(段错误SIGSEGV):程序运行时访问了操作系统未授权的内存地址,触发内存访问违规,属于运行阶段才会出现的问题。
  • code 10类编译报错:代码的寻址逻辑不符合x86指令集的语法规则,链接器无法计算出合法内存地址,在编译阶段就会被拦截,程序根本无法启动。

原代码触发问题的具体原因

  1. 非法栈跳转触发段错误
    程序被操作系统直接加载到内存执行时,入口点_start是被内核直接跳转进入的,栈上不存在普通函数调用的返回地址。你在.printthis块调用完打印系统调用后直接写了ret,会把栈顶存的命令行参数值当作返回地址跳转,直接访问到无权限的低地址空间,这是触发signal11的核心原因。
    原本写在jmp .printthis之后的标准退出代码mov eax,1; int 0x80被无条件跳转直接跳过,根本没有执行到正确的程序退出逻辑。
  2. 数组访问的尺寸不匹配
    你用db声明的数组每个元素仅占1字节,但你写mov eax, [array]是按32位尺寸从内存读值,会一次性连续读取从array起始地址开始的4个字节(也就是1、2、3、4四个相邻元素)拼成一个32位整数存入eax,完全和“取数组第一个元素的值为1”的预期不符。
  3. 非法寻址触发编译报错
    你尝试写的mov eax, [array*4]会直接触发code10报错,原因是 x86指令集的寻址规则中,比例因子仅允许作用在寄存器上,不允许直接乘在数据标签上。合法的比例寻址格式只能是「基址寄存器 + 索引寄存器*比例因子(1/2/4/8) + 立即数偏移」,把array标签直接乘4属于完全不符合语法的写法,链接器无法计算对应地址,自然编译失败。
    你之前写的mov ebx, [array+1]语法是合法的,只是因为按32位尺寸读单字节数组,会把相邻的内存字节都读入ebx,得到的是不符合预期的脏值。

可正常运行的修正代码

section .text
global _start
_start:
    ; 按字节尺寸读取单字节数组元素,避免读入相邻的脏值
    mov     al, [array]
    mov     bl, [array+1]
    add     al, bl
    ; 要输出可见数字的话,需要把数值转成对应ASCII编码
    add     al, 0x30
    mov     [sum], al

.printthis:
    mov     ecx, sum
    mov     edx, 1
    mov     ebx, 1
    mov     eax, 4
    int     0x80
    ; 打印完成后走标准系统调用退出,不能使用ret
    mov     eax, 1
    int     0x80

section .data
    array   db 1,2,3,4,5

section .bss
    sum     resb 1

核心知识点梳理

  • 32位x86 Linux的用户程序必须通过int 0x80的exit系统调用主动退出,不能依赖普通函数的ret指令返回——因为程序入口没有被常规函数调用,栈上不存在合法的返回地址。
  • 不同尺寸的内存读取指令要和数组声明匹配:
    • 用db声明的1字节数组,读取时要用mov al/bl/cl...这类8位寄存器存值
    • 用dw声明的2字节数组,读取时要用mov ax/bx/cx...这类16位寄存器存值
    • 用dd声明的4字节数组,读取时用32位寄存器即可
  • 合法的索引访问写法:如果要访问数组里第i个4字节元素,需要先把索引值存到寄存器中,再写mov eax, [array + esi*4],不能直接对array标签做乘法操作。
  • 段错误的高频触发场景:无权限的内存读写、非法栈跳转、跳转到不可执行的内存区域。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.06 15:54:09