鱼C论坛

 找回密码
 立即注册
查看: 348|回复: 2

[已解决]大神们,我这又有问题了

[复制链接]
发表于 2024-3-13 22:06:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
;名称: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:[si]                ;将先产存入的ASCII码出栈到内存
                        inc si              ;每出栈一次,将偏移量加一
                        loop nu_out                ;循环
                        ret

                       
                       
code ends
end start       
在DEBUG当中可以正常通过,为什么运行时就报告溢出了呢
最佳答案
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:[si]                ;将先产存入的ASCII码出栈到内存
                        inc si              ;每出栈一次,将偏移量加一
                        loop nu_out                ;循环
                        ret
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-3-13 22:07:07 | 显示全部楼层
你好!从你提供的代码看,溢出问题可能出现在以下几个地方:

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

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

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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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:[si]                ;将先产存入的ASCII码出栈到内存
                        inc si              ;每出栈一次,将偏移量加一
                        loop nu_out                ;循环
                        ret
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 18:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表