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

Linux下MIPS汇编递减栈指针触发SEGFAULT的原因排查

MIPS汇编Pacman游戏栈指针递减触发段错误问题

我在为Linux终端编写小端模式的MIPS汇编版Pacman游戏(纯兴趣尝试),但在initializeScreen函数中遇到了一个奇怪的段错误:执行栈指针递减指令时触发SEGFAULT。

错误发生在以下代码的最后一条指令:

#Print it
add $a0, $s0, $zero
add $a1, $zero, $zero
add $a2, $zero, $zero
add $a3, $zero, $zero
addi $sp, $sp, -4

排查情况

  • 最初猜测是程序.text段空间不足,但GDB输出显示指令地址完全正常:
(gdb) x/6iw $pc
=> 0x400e88 <initializeScreen+432>:     addi    sp,sp,-4
   0x400e8c <initializeScreen+436>:     sw  s1,0(sp)
   0x400e90 <initializeScreen+440>:     lw  t8,96(s7)
   0x400e94 <initializeScreen+444>:     nop
   0x400e98 <initializeScreen+448>:     jalr    t8
   0x400e9c <initializeScreen+452>:     nop
  • 第二个猜想是栈空间耗尽,但Linux默认栈空间为KB或MB级别,而我的汇编代码仅用栈存储寄存器值,这个可能性极低。另外,出错时$sp的取值为0x407fff7c。

完整的initializeScreen函数代码

initializeScreen: 
    #Save return address
    addi $sp, $sp, -4
    sw $ra, ($sp)

    #Save s registers
    addi $sp, $sp, -4
    sw $s0, ($sp)
    addi $sp, $sp, -4
    sw $s1, ($sp)
    
    #Initialize screen. 
    #Step #1: Clear the screen. 
    #Step #2: Display the high score, current level, and points. 
    #Step #3: Draw the maze. 
    #Step #4: Draw pacman. 
    #Step #5: Draw the ghosts. 
    #Step #6: Draw the power pellets. 
    #Step #7: Display the number of lives remaining. 

    #Step #1: Clear the screen. 
    la $a0, buffer
    #jal storeClearToString
    lw $t8, 76($s7)
    jalr $t8

    addi $a0, $a0, 4
    #jal storeRTOToString
    lw $t8, 80($s7)
    jalr $t8

    #Print
    addi $a0, $zero, 1
    la $a1, buffer
    addi $a2, $zero, 8
    addi $v0, $zero, 4004
    syscall

    #Step #2: Display the high score, current level, and points. 
    #Current level (1st byte)
    #Print the text
    addi $a0, $zero, 1
    la $a1, levelText
    addi $a2, $zero, 15
    addi $v0, $zero, 4004
    syscall
    #Print the number
    lw $s0, 0($s6)
    add $a0, $s0, $zero
    addi $t1, $zero, 24
    sll $a0, $a0, $t1
    srl $a0, $a0, $t1
    #jal printInt
    lw $t8, 24($s7)
    jal $t8

    #Print '\n'
    addi $a0, $zero, 1
    la $a1, newline2
    addi $a2, $zero, 1
    addi $v0, $zero, 4004
    syscall

    #High score (2nd byte)
    #Note for the future: Might want to allocate more memory for the scores. 
    #Print the text
    addi $a0, $zero, 1
    la $a1, highScoreText
    addi $a2, $zero, 12
    addi $v0, $zero, 4004
    syscall
    #Print the number
    add $a0, $s0, $zero
    addi $t1, $zero, 16
    sll $a0, $a0, $t1
    addi $t1, $zero, 24
    srl $a0, $a0, $t1
    #jal printInt
    lw $t8, 24($s7)
    jal $t8

    #Print '\n'
    addi $a0, $zero, 1
    la $a1, newline2
    addi $a2, $zero, 1
    addi $v0, $zero, 4004
    syscall

    #Number of points (4th byte)
    #Print the text
    addi $a0, $zero, 1
    la $a1, pointsCollText
    addi $a2, $zero, 18
    addi $v0, $zero, 4004
    syscall
    #Print the number
    add $a0, $s0, $zero
    addi $t1, $zero, 24
    srl $a0, $a0, $t1
    #jal printInt
    lw $t8, 24($s7)
    jal $t8

    #Print '\n'
    addi $a0, $zero, 1
    la $a1, newline2
    addi $a2, $zero, 1
    addi $v0, $zero, 4004
    syscall

    #Step #3: Print the maze. 
    #Create the drawing array
    addi $a0, $zero, 10
    addi $a1, $zero, 10
    addi $a2, $zero, 4
    #jal createNewTwoDArray
    lw $t8, 44($s7)
    jalr $t8
    add $s0, $v0, $zero
    
    #Test: Print a rectangle. 
    #Create the Rectangle
    addi $a0, $zero, 7
    addi $a1, $zero, 7
    #jal createNewRectangle
    lw $t8, 92($s7)
    jalr $t8
    add $s1, $v0, $zero
    #Print it
    add $a0, $s0, $zero
    add $a1, $zero, $zero
    add $a2, $zero, $zero
    add $a3, $zero, $zero
    addi $sp, $sp, -4
    sw $s1, ($sp)
    #jal drawRectangle
    lw $t8, 96($s7)
    jalr $t8

    #Exit:
    lw $s1, ($sp)
    addi $sp, $sp, 4
    lw $s0, ($sp)
    addi $sp, $sp, 4
    lw $ra, ($sp)
    addi $sp, $sp, 4
    jr $ra

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:30:03