鱼C论坛

 找回密码
 立即注册
查看: 1382|回复: 3

[已解决]实验10.3程序执行过程中数据损坏

[复制链接]
发表于 2022-6-27 18:22:42 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 玛丽亚在伯大尼 于 2022-6-27 18:36 编辑

用DEBUG调试过了,发现从c1:mov bx,0处开始原本定义好的数据发生了变化(之后越变越离谱),然而前面没有执行改变数据的指令
我想请教一下各位大佬,这是由什么导致的
下面是代码:
assume ds:data,cs:code,ss:stack
data segment
dw 123,12666,1,8,3,38,10
;db 64 dup (0)
data ends

stack segment
dw 16 dup (0)
stack ends

code segment
main:mov ax,data
        mov ds,ax
        mov cx,6
        mov si,0
        mov di,0
        mov sp,32
c1:        mov bx,0    ;从这里开始出现问题
        push cx
        call dtoc
        pop cx
        inc si
        loop c1
        mov ax,4C00H
        int 21H

dtoc:mov ax,[si]               
        push si
        mov cx,ax
        jcxz c4
c2:        mov dx,0                        ;取各个位上的数压栈
        mov si,12
        div word ptr [si]
        mov cx,ax
        jcxz c4
        add dx,30H
        push dx
        inc bx
        jmp c2
c4:        add dx,30H
        push dx
        inc bx
        mov cx,bx
c3:        pop [di+16]                ;将转换好的数写入数据段
        inc di
        loop c3
        inc di
        pop si
        ret
code ends
END main
最佳答案
2022-6-28 14:57:21
本帖最后由 jackz007 于 2022-6-28 15:57 编辑
玛丽亚在伯大尼 发表于 2022-6-28 10:12
哥,我提问主要是想知道数据为什么会被改掉,代码怎么写倒不是特别重要
不过也感谢你的回答


         代码问题有 3 个,其中最主要的 1 个是没有为堆栈段赋值,从而导致堆栈段上半部分的 16 个字节与数据段相重叠,堆栈数据意外侵占数据段内容。
  1. assume ds:data,cs:code,ss:stack
  2. data segment
  3.         dw 123,12666,1,8,3,38,10
  4.         ;db 64 dup (0)
  5. data ends

  6. stack segment
  7.         dw 200h dup (0)     ; 【问题1】:堆栈段为什么定义得那么小?- 已修正
  8. stack ends

  9. code segment
  10. main:mov ax,data
  11.         mov ds,ax
  12.         mov ax,stack        ; 【问题2】:堆栈段为何不赋值?- 此行新加
  13.         mov ss,ax           ; 【问题2】:堆栈段为何不赋值?- 此行新加
  14.         mov sp,400h         ; 堆栈段容量调整,此句进行相应的修改,各个段的初始化代码最好放在所有语句的最前面。
  15.         mov cx,6
  16.         mov si,0
  17.         mov di,0
  18. c1:     mov bx,0
  19.         push cx
  20.         call dtoc
  21.         pop cx
  22.         add si,2            ; 【问题3】:一个 16 位整型数占用的是 2 个字节,这里 si 为何只加 1?- 已修正
  23.         loop c1
  24.         mov ax,4C00H
  25.         int 21H

  26. dtoc:mov ax,[si]               
  27.         push si
  28.         mov cx,ax
  29.         jcxz c4
  30. c2:     mov dx,0
  31.         mov si,12
  32.         div word ptr [si]
  33.         mov cx,ax
  34.         jcxz c4
  35.         add dx,30H
  36.         push dx
  37.         inc bx
  38.         jmp c2
  39. c4:     add dx,30H
  40.         push dx
  41.         inc bx
  42.         mov cx,bx
  43. c3:     pop [di+16]
  44.         inc di
  45.         loop c3
  46.         inc di
  47.         pop si
  48.         ret
  49. code ends
  50. end main
复制代码

            堆栈问题最简单的解决方法是删除 mov sp,32 这一句也同样可以解决问题。
            堆栈段的定义和初始化方法楼主可以参考我的代码,只要伪指令应用得当,堆栈段其实是不需要任何初始化的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-6-27 22:34:44 | 显示全部楼层
本帖最后由 jackz007 于 2022-6-28 08:39 编辑

        试试这个代码吧
  1. assume cs:code , ds:data

  2. data segment para public 'data'
  3.         dw 123,12666,1,8,3,38,10
  4. data ends

  5. edata segment para public 'edata'
  6.         db 10h dup(0)
  7. edata ends

  8. stack segment para stack 'stack'
  9.         dw 400h dup(0)
  10. stack ends

  11. code segment para public 'code'

  12. dtoc proc near
  13.         push bp
  14.         mov bp,sp
  15.         push ax
  16.         push bx
  17.         push cx
  18.         push dx
  19.         push si
  20.         push ds
  21.         mov ax,edata
  22.         mov ds,ax
  23.         mov ax,[bp+4]   
  24.         xor bx,bx
  25.         push bx
  26.         mov cx,10
  27. d01:    xor dx,dx
  28.         div cx
  29.         add dl,30h
  30.         mov byte ptr[bx],dl
  31.         inc bx
  32.         or ax,ax
  33.         jnz d01
  34.         cmp bx,2
  35.         jb d03
  36.         xor si,si
  37.         mov cx,bx
  38.         shr cx,1
  39.         lea di,[bx-1]
  40. d02:    mov al,byte ptr[si]
  41.         xchg al,byte ptr[di]
  42.         xchg al,byte ptr[si]
  43.         inc si
  44.         dec di
  45.         loop d02
  46. d03:    mov byte ptr[bx],0ah
  47.         mov byte ptr[bx+1],0dh
  48.         mov byte ptr[bx+2],'$'
  49.         mov byte ptr[bx+3],00h
  50.         pop dx
  51.         mov ah,09h
  52.         int 021h
  53.         pop ds
  54.         pop si
  55.         pop dx
  56.         pop cx
  57.         pop bx
  58.         pop ax
  59.         mov sp,bp
  60.         pop bp
  61.         ret 02
  62. dtoc endp

  63. main proc far
  64.         mov ax,data
  65.         mov ds,ax
  66.         xor bx,bx
  67.         mov cx,7
  68. m01:    push word ptr[bx]
  69.         call dtoc
  70.         add bx,2
  71.         loop m01        
  72.         mov ax,4c00h
  73.         int 021h
  74. main endp
  75. code ends
  76. end main
复制代码

        这个代码无需借助于 debug.exe,直接运行就可以从屏幕上看到那 7 个数值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-6-28 10:12:00 | 显示全部楼层
jackz007 发表于 2022-6-27 22:34
试试这个代码吧

        这个代码无需借助于 debug.exe,直接运行就可以从屏幕上看到那 7 个数 ...

哥,我提问主要是想知道数据为什么会被改掉,代码怎么写倒不是特别重要
不过也感谢你的回答
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-6-28 14:57:21 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2022-6-28 15:57 编辑
玛丽亚在伯大尼 发表于 2022-6-28 10:12
哥,我提问主要是想知道数据为什么会被改掉,代码怎么写倒不是特别重要
不过也感谢你的回答


         代码问题有 3 个,其中最主要的 1 个是没有为堆栈段赋值,从而导致堆栈段上半部分的 16 个字节与数据段相重叠,堆栈数据意外侵占数据段内容。
  1. assume ds:data,cs:code,ss:stack
  2. data segment
  3.         dw 123,12666,1,8,3,38,10
  4.         ;db 64 dup (0)
  5. data ends

  6. stack segment
  7.         dw 200h dup (0)     ; 【问题1】:堆栈段为什么定义得那么小?- 已修正
  8. stack ends

  9. code segment
  10. main:mov ax,data
  11.         mov ds,ax
  12.         mov ax,stack        ; 【问题2】:堆栈段为何不赋值?- 此行新加
  13.         mov ss,ax           ; 【问题2】:堆栈段为何不赋值?- 此行新加
  14.         mov sp,400h         ; 堆栈段容量调整,此句进行相应的修改,各个段的初始化代码最好放在所有语句的最前面。
  15.         mov cx,6
  16.         mov si,0
  17.         mov di,0
  18. c1:     mov bx,0
  19.         push cx
  20.         call dtoc
  21.         pop cx
  22.         add si,2            ; 【问题3】:一个 16 位整型数占用的是 2 个字节,这里 si 为何只加 1?- 已修正
  23.         loop c1
  24.         mov ax,4C00H
  25.         int 21H

  26. dtoc:mov ax,[si]               
  27.         push si
  28.         mov cx,ax
  29.         jcxz c4
  30. c2:     mov dx,0
  31.         mov si,12
  32.         div word ptr [si]
  33.         mov cx,ax
  34.         jcxz c4
  35.         add dx,30H
  36.         push dx
  37.         inc bx
  38.         jmp c2
  39. c4:     add dx,30H
  40.         push dx
  41.         inc bx
  42.         mov cx,bx
  43. c3:     pop [di+16]
  44.         inc di
  45.         loop c3
  46.         inc di
  47.         pop si
  48.         ret
  49. code ends
  50. end main
复制代码

            堆栈问题最简单的解决方法是删除 mov sp,32 这一句也同样可以解决问题。
            堆栈段的定义和初始化方法楼主可以参考我的代码,只要伪指令应用得当,堆栈段其实是不需要任何初始化的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-14 03:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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