liuming1978 发表于 2024-3-13 22:06:35

大神们,我这又有问题了

;名称:doct
;功能:将word型数据转变为表示十进制数的字符串,字符串以0结尾符。
;参数:(ax)=word型数据
;                ds:si指向字符串的首地址
;返回:无
;应用举例:编程,将数据12666以十进制的形式在屏幕上8行3列,用绿色显示出来。在显示时我们调用本次实难中的第一个子程序show_str.
assume cs:code,ds:data
data segment
                db 10 dup(0)
data ends
code segment
start:                mov ax,12666
                        mov bx,data
                        mov ds,bx
                        mov si,0
                        call dtoc
                       
;                        mov dh,8
;                        mov dl,3
;                        mov cl,2
;                        call show_str
                       

                       
                       
                        mov ax,4c00h
                        int 21h
;*******************************                       
dtoc:                xor bx,bx                ;bx归零,准备用做计数器
                        mov bx,0
nu_in:                mov cx,10                ;将cx用做除数
                        div cx                        ;除以CX,因为使用的是十六位除法,所以,商保存在AX里,余数保存在DX里
                        add dl,30h                ;将余数加30H,得到ASCII码
                        push dx                        ;将DX入栈保存,使用栈的保存规则,使得到的ASCII码一会会以正序表达
                        xor dx,dx                ;dx清零
                        inc bx                        ;计数器BX自增1
                        mov cx,ax                ;将商赋给CX,以便JCXZ指令检测CX是否为零
                        jcxz pop_number        ;JCXZ指令检测CX是否为零
                        jmp nu_in                ;如果CX不为零,则跳回到NU——IN处重新开始程序
                       
pop_number:        mov cx,bx                ;从此处开始向内存处写处ASCII码,这一步是先将先前得到的入栈次数做为循环次数使用
nu_out:                pop ds:                ;将先产存入的ASCII码出栈到内存
                        inc si              ;每出栈一次,将偏移量加一
                        loop nu_out                ;循环
                        ret

                       
                       
code ends
end start       
在DEBUG当中可以正常通过,为什么运行时就报告溢出了呢

FishC 发表于 2024-3-13 22:07:07

你好!从你提供的代码看,溢出问题可能出现在以下几个地方:

1. 数据段定义:你的数据段定义中,只有10个字节(10 dup(0)),是否足够存储转换后的字符串呢?如果不够长,转换后的字符串就会超出数据段的范围,导致溢出。你可以尝试将数据段长度增加到足够大的值。

2. 栈溢出:在dtoc子程序中,你使用了栈来保存转换后的ASCII码。但你并没有定义栈的大小,如果栈的大小不够容纳所有的ASCII码,就会发生栈溢出。你可以尝试增加栈的大小,或改用其他方式保存转换后的ASCII码。

3. 内存溢出:在nu_out标签处,你使用了循环将ASCII码从栈中取出并写入内存。如果写入内存的位置超过了内存的有效范围,就会发生内存溢出。你可以检查一下ds寄存器指向的内存段是否足够大,以及si寄存器是否正确地指向了数据段的首地址。

希望以上提示对你有所帮助,如果还有疑问,请随时追问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

人造人 发表于 2024-3-13 23:48:37

dtoc:                xor bx,bx                ;bx归零,准备用做计数器
                        ;mov bx,0
                           mov dx,0 ; 这样 ?
                                             ; dx:ax / cx

nu_in:                mov cx,10                ;将cx用做除数
                        div cx                        ;除以CX,因为使用的是十六位除法,所以,商保存在AX里,余数保存在DX里
                        add dl,30h                ;将余数加30H,得到ASCII码
                        push dx                        ;将DX入栈保存,使用栈的保存规则,使得到的ASCII码一会会以正序表达
                        xor dx,dx                ;dx清零
                        inc bx                        ;计数器BX自增1
                        mov cx,ax                ;将商赋给CX,以便JCXZ指令检测CX是否为零
                        jcxz pop_number      ;JCXZ指令检测CX是否为零
                        jmp nu_in                ;如果CX不为零,则跳回到NU——IN处重新开始程序
                     
pop_number:      mov cx,bx                ;从此处开始向内存处写处ASCII码,这一步是先将先前得到的入栈次数做为循环次数使用
nu_out:                pop ds:                ;将先产存入的ASCII码出栈到内存
                        inc si            ;每出栈一次,将偏移量加一
                        loop nu_out                ;循环
                        ret
页: [1]
查看完整版本: 大神们,我这又有问题了