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

我的x64汇编代码出现段错误,请求定位问题位置

解决x64汇编代码段错误问题

以下是你的代码触发段错误的核心原因及对应修复方案:

1. _start入口的冗余ret指令

_start是程序的入口点,并非通过call调用的函数,栈中没有合法的返回地址。你在exit系统调用后添加的ret会尝试读取栈顶的垃圾地址,直接引发段错误。
修复:删除_start末尾的ret指令,exit系统调用会直接终止程序,无需返回操作。

2. 运算标签中的非法ret

通过je跳转到_mult、_div等标签时,并没有通过call建立栈帧,栈中不存在有效的返回地址。执行这些标签内的ret会触发栈访问错误。
修复:将标签内的ret替换为退出逻辑,比如调用Exit宏:

_mult:    
    Exit
_div:
    Exit
_add:
    Exit
_sub:
    Exit

3. PrintString宏的栈不平衡问题

宏开头执行push rax保存寄存器,但后续未执行pop rax恢复,导致栈结构始终不平衡,后续操作会破坏栈状态引发错误。
修复:在syscall之后添加pop rax恢复栈:

%macro PrintString 1
    mov rax, %1
    push rax
    mov rbx, 0
    %%Length:
        inc rax
        inc rbx
        mov cl, [rax]
        cmp cl, 0
        jne %%Length

        mov rax, 1
        mov rdi, 1
        mov rsi, %1
        mov rdx, rbx
        syscall
    pop rax  ; 恢复栈平衡
%endmacro

4. stringToInteger宏的致命逻辑错误

这个宏存在多处错误,即使暂时未调用,后续使用也会触发段错误:

  • PLACE equ $10中的$是宏展开的当前地址,导致PLACE被定义为当前地址+10,而非十进制基数10,应改为PLACE equ 10;
  • add [rax], cl中rax初始为0,直接访问内存地址0属于非法操作,正确逻辑应将计算结果存在rax寄存器中,而非内存;
  • 整体字符串转整数的逻辑混乱,需重新梳理为从字符串起始位置逐个字符处理、累加计算数值的流程。

修复后的主文件示例

%include "utils.inc"

section .data
    intro db "Enter 2 numbers and an operation symbol : ", 10, 0
    outro db "Your answer is : "
    number1 db "Num 1 : ", 0
    number2 db "Num 2 : ", 0
    operation db "Operation : ", 0
    error db "Invalid Operation", 0

section .bss
    num1 resb 6 ; reserve 6 characters for the first number
    num2 resb 6 ; reserve 6 characters for the second number
    operand resb 1 ; reserve 1 character for the operation

section .text
    global _start

_start:
    PrintString intro

    ; get the first number
    PrintString number1
    mov rax, 0
    mov rdi, 0
    mov rsi, num1
    mov rdx, 6  ; 改为预留长度,避免输入截断
    syscall

    ; get the second number
    PrintString number2
    mov rax, 0
    mov rdi, 0
    mov rsi, num2
    mov rdx, 6 
    syscall

    ; get the operation
    PrintString operation
    mov rax, 0
    mov rdi, 0
    mov rsi, operand
    mov rdx, 2  ; 读取操作符+回车,避免残留输入滞留缓冲区
    syscall

    mov al, [operand]

    ; if the operation is '*'
    cmp al, 42
    je _mult
    
    ; if the operation is '/'
    cmp al, 47
    je _div

    ; if the operation is '+'
    cmp al, 43
    je _add

    ; if the operation is '-'
    cmp al, 45
    je _sub

    Exit  ; 直接调用Exit宏退出

_mult:    
    Exit
_div:
    Exit
_add:
    Exit
_sub:
    Exit

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:05:58