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

TASM(DosBOX环境)数字打印程序异常:乱码且冻结求助

汇编程序输出乱码并冻结的修复方案

问题描述

在DOSBox模拟器中使用TASM开发的汇编程序,预期输出两行计算结果:

25 + 10 = 35
25 - 10 = 15

但实际运行时会打印乱码,且程序冻结。原始代码如下:

SSEG    segment stack   
        db 256 dup(0)
SSEG    ends

DSEG    segment         
   num1 dw 25
   num2 dw 10
   new_line db 0dh,0ah,'$'
   msg_add db '25 + 10 = ','$'
   msg_sub db '25 - 10 = ','$'
DSEG    ends

CSEG    segment         
        assume cs:CSEG,ds:DSEG,ss:SSEG
    

begin:
    
    
    mov ax, DSEG    
    mov ds, ax      
    
    ; ADD
    mov ah, 09h
    mov dx, offset msg_add
    int 21h
    mov ax, num1
    mov bx, num2
    add ax, bx

    mov ax, ax
    call print_number

    
    ; SUB
    mov ah, 09h
    mov dx, offset msg_sub
    int 21h
    mov ax, num1
    mov bx, num2
    sub ax, bx

    mov ax, ax
    call print_number

    print_number proc

        mov si,10
        mov cx,0
    a:
        mov dx,0
        div si
        add dx,'0'
        push dx
        inc cx
        cmp ax,0
        jnz a
    aa:
        pop dx
        mov ah,02h
        int 21h
        loop aa
    
        mov ah, 09h
        mov dx, offset new_line
        int 21h
        
        
        
        ret
    print_number endp

    mov ah,4ch      
    int 21h         
    
    
CSEG    ends        
end begin           

尝试过的无效方案

  1. 栈传参方式
    调用代码:
mov ah, 09h
mov dx, offset msg_add
int 21h
mov ax, num1
mov bx, num2
add ax, bx
push ax
call print_number
  • 错误弹出写法(直接弹出返回地址):
print_number proc
        pop ax
        mov si,10
        mov cx,0
    a:
        mov dx,0
        div si
        add dx,'0'
        push dx
        inc cx
        cmp ax,0
        jnz a
    aa:
        pop dx
        mov ah,02h
        int 21h
        loop aa
    
        mov ah, 09h
        mov dx, offset new_line
        int 21h
    
        
        ret
print_number endp
  • 冗余压入写法(未保存寄存器):
print_number proc
        push ax
        mov si,10
        mov cx,0
    a:
        mov dx,0
        div si
        add dx,'0'
        push dx
        inc cx
        cmp ax,0
        jnz a
    aa:
        pop dx
        mov ah,02h
        int 21h
        loop aa
    
        mov ah, 09h
        mov dx, offset new_line
        int 21h

        
        ret
print_number endp
  1. 寄存器传参方式
    调用代码与原始代码一致,过程实现也未做调整,未解决问题。

核心问题分析

  1. 过程定义位置错误:原始代码中print_number proc放在主程序执行流程中间,主程序调用完两次print_number后,会直接进入过程代码执行,而非执行退出指令mov ah,4ch,导致程序进入错误流程。
  2. 寄存器未保存恢复:过程中使用的ax、cx、dx、si寄存器会破坏主程序的寄存器状态,引发后续逻辑错误。
  3. 栈传参写法错误:pop ax直接弹出栈中的返回地址,导致ret指令无法正确返回主程序,引发崩溃。

修复后的完整代码

采用AX寄存器传递待打印数字的方式,修正后的代码如下:

SSEG    segment stack   
        db 256 dup(0)
SSEG    ends

DSEG    segment         
   num1 dw 25
   num2 dw 10
   new_line db 0dh,0ah,'$'
   msg_add db '25 + 10 = ','$'
   msg_sub db '25 - 10 = ','$'
DSEG    ends

CSEG    segment         
        assume cs:CSEG,ds:DSEG,ss:SSEG

; 过程定义移到主程序执行路径之外
print_number proc
        push ax          ; 保存用到的寄存器
        push cx
        push dx
        push si

        mov si,10
        mov cx,0
a:
        mov dx,0
        div si
        add dx,'0'
        push dx
        inc cx
        cmp ax,0
        jnz a
aa:
        pop dx
        mov ah,02h
        int 21h
        loop aa
    
        mov ah, 09h
        mov dx, offset new_line
        int 21h

        pop si           ; 恢复寄存器
        pop dx
        pop cx
        pop ax
        ret
print_number endp

begin:
    mov ax, DSEG    
    mov ds, ax      
    
    ; ADD
    mov ah, 09h
    mov dx, offset msg_add
    int 21h
    mov ax, num1
    add ax, num2       ; 直接相加,无需BX中转
    call print_number

    ; SUB
    mov ah, 09h
    mov dx, offset msg_sub
    int 21h
    mov ax, num1
    sub ax, num2       ; 直接相减,无需BX中转
    call print_number

    mov ah,4ch      
    int 21h         
    
CSEG    ends        
end begin           

关键修复点说明

  1. 调整过程位置:将print_number proc移到主程序begin:之前,避免主程序意外进入过程代码。
  2. 寄存器保护:过程开头用push保存用到的寄存器,结尾用pop恢复,防止破坏主程序的寄存器状态。
  3. 简化传参逻辑:直接用AX传递待打印数字,去掉冗余的mov ax, ax代码,计算时直接操作AX,简化逻辑。
  4. 正确处理栈:避免直接弹出返回地址的错误写法,寄存器传参更简单高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:14:54