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

AT&T汇编构建输入数字向量报错段错误,求修正方案

AT&T汇编段错误问题排查与修复

问题描述

要将输入数字(1、4、3、5、10)存入向量v,编写的AT&T汇编代码运行时触发“Segmentation fault (core dumped)”错误,以下是原代码:

.data 
    v: .space 128 # 为向量分配的空间
    N: .space 4 # 存储单个输入数字
    n: .space 4 # 存储输入数字的个数
    indexV: .space 4 
    index: .space 4
    formatScanf: .asciz "%ld"
    formatPrintf: .asciz "%ld "
.text
.global main 
main:

    pushl $n
    pushl $formatScanf
    call scanf
    popl %ebx
    popl %ebx
    
lea v, %edi
movl $0, indexV
et_vector: 
            
        movl indexV, %ecx
        cmp %ecx, n
        je et_print

        pushl $N
        pushl $formatScanf
        call scanf
        popl %ebx
        popl %ebx
        
        movl $N, (%edi, %ecx, 4)
        incl indexV

    jmp et_vector

movl $0, index
et_print:
movl index, %ecx
cmp %ecx, n
je et_exit
lea v, %edi
movl (%edi, %ecx, 4), %ebx

pushl %ebx
pushl $formatPrintf
call printf
popl %ebx
popl %ebx
pushl $0
call fflush
popl %ebx
incl index
jmp et_print


et_exit:
movl $1, %eax
movl $0, %ebx
int $0x80

错误分析与修复点

  • 格式符类型不匹配:%ld是64位长整型格式符,但n、N都是4字节的32位整型变量,scanf会尝试写入8字节数据,直接越界破坏内存,引发段错误。需将formatScanf和formatPrintf的格式符改为%d。
  • 错误取N的地址而非值:movl $N, (%edi, %ecx, 4)中$N是取N的内存地址,不是存储的输入值,应改为movl N, (%edi, %ecx, 4),取N变量里的数值存入向量。
  • cmp指令操作数顺序错误:AT&T汇编中cmp 源, 目的的逻辑是目的 - 源,原代码cmp %ecx, n实际是计算n - %ecx,逻辑上要判断索引%ecx是否等于输入个数n,应改为cmp n, %ecx,相等时跳转至打印逻辑。
  • 立即数直接写入内存非法:x86 32位汇编不支持movl $0, indexV这种直接把立即数存到内存变量的操作,需通过寄存器中转,比如movl $0, %eax; movl %eax, indexV,同理movl $0, index也要做相同修改。

修复后的完整代码

.data 
    v: .space 128 # 为向量分配的空间
    N: .space 4 # 存储单个输入数字
    n: .space 4 # 存储输入数字的个数
    indexV: .space 4 
    index: .space 4
    formatScanf: .asciz "%d"
    formatPrintf: .asciz "%d "
.text
.global main 
main:
    # 读取输入数字的个数n
    pushl $n
    pushl $formatScanf
    call scanf
    popl %ebx
    popl %ebx
    
    lea v, %edi
    # 初始化索引indexV为0
    movl $0, %eax
    movl %eax, indexV

et_vector: 
    movl indexV, %ecx
    # 判断索引是否等于n,相等则跳转打印
    cmp n, %ecx
    je et_print

    # 读取单个输入数字到N
    pushl $N
    pushl $formatScanf
    call scanf
    popl %ebx
    popl %ebx
    
    # 将N的值存入向量v的对应位置
    movl N, (%edi, %ecx, 4)
    # 索引自增
    incl indexV
    jmp et_vector

et_print:
    # 初始化打印索引为0
    movl $0, %eax
    movl %eax, index

print_loop:
    movl index, %ecx
    # 判断打印索引是否等于n,相等则退出
    cmp n, %ecx
    je et_exit
    
    lea v, %edi
    movl (%edi, %ecx, 4), %ebx

    # 打印当前元素
    pushl %ebx
    pushl $formatPrintf
    call printf
    popl %ebx
    popl %ebx
    
    # 刷新输出缓冲区
    pushl $0
    call fflush
    popl %ebx
    
    # 打印索引自增
    incl index
    jmp print_loop

et_exit:
    # 系统调用退出程序
    movl $1, %eax
    movl $0, %ebx
    int $0x80

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:35:27