鱼C论坛

 找回密码
 立即注册
查看: 3764|回复: 5

[已解决]实验九,“MOV ES:[DI],AL”无法写入数据

[复制链接]
发表于 2019-8-20 10:54:27 | 显示全部楼层 |阅读模式

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

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

x
代码与小甲鱼视频中的代码略有差异。代码如下
ASSUME CS:CODE,DS:DATA,SS:STACK
DATA SEGMENT
        DB 'welcome to masm!'
        db 02h,24h,71h
DATA ENDS

STACK SEGMENT
        DW 8 DUP(0)
STACK ENDS

CODE SEGMENT
START:
                MOV AX,DATA
                MOV DS,AX   ;DS为数据源
                MOV BX,0
                MOV AX,STACK
                MOV SS,AX
                MOV SP,10H
                MOV AX,0B872H
                
                MOV CX,3
S:                
                PUSH CX
                PUSH AX
                MOV ES,AX   ;ES为目的数据段地址,初次地址为B872H
                MOV SI,0
                MOV DI,0
                MOV CX,10H
S1:                
                MOV AL,DS:[SI] ;每次循环,从DS:[SI]中取出数据,存储到AL中
                MOV ES:[DI],AL ;每次循环,将AL中的数据放入到ES:[DI]中
                INC SI
                ADD DI,2
                LOOP S1
                                
                MOV DI,0
                POP BX
                MOV AL,DS:10H[BX] ;取出颜色
                MOV CX,10H
S2:
                MOV ES:1[DI],AL  ;写入颜色
                ADD DI,2
                LOOP S2
                
                POP AX
                POP CX
                ADD AX,0AH
                INC BX
                LOOP S        
                
                MOV AX,4C00H
                INT 21H                
CODE ENDS
END START
                

问题如下:
通过调试可知,通过“MOV AL,DS:[SI]”可以读取目标数据存入AL,但是“MOV ES:[DI],AL ”无法将AL写入到ES:[DI](初次写入位置B8720H),这是为啥呢。。。。求指教。
最佳答案
2019-8-20 12:19:26
本帖最后由 jackz007 于 2019-8-20 14:35 编辑
                MOV DI,0
                POP BX            ; 这一句破坏了堆栈平衡
                MOV AL,DS:10H[BX] ; 取出颜色

      改成下面这样就可以了:
                MOV DI,0
                XOR BX,BX         ; 让 BX 指向数据段开头位置(0 偏移)
                MOV AL,DS:10H[BX] ; 取出颜色

      由于堆栈平衡被破坏,在循环中,ES 的值不正确,导致无法正常显示信息。

      楼主可以参考一下我修改的代码:
ASSUME CS:CODE , DS:DATA

DATA SEGMENT PARA PUBLIC 'DATA'
 MESSAGE DB 'welcome to masm!' , 00h
  COLOR DB 02h
DATA ENDS

STACK SEGMENT STACK
        DW 8 DUP(0)
STACK ENDS

CODE SEGMENT PARA PUBLIC 'CODE'
MAIN PROC FAR
                MOV AX,DATA
                MOV DS,AX              ;DS为数据源
                MOV AX,0B872H
                MOV CX,3
                CLD
            M1: MOV ES,AX
                PUSH AX
                MOV SI,OFFSET MESSAGE
                XOR DI,DI
            M2: LODSB
                OR AL,AL
                JZ M3
                STOSB
                MOV AL,COLOR
                STOSB
                JMP M2                 
            M3: POP AX
                ADD AX,0AH
                LOOP M1
                XOR AX,AX
                INT 016H
                MOV AX,4C00H
                INT 21H                
MAIN ENDP
CODE ENDS
END MAIN

    任何时候,想退出 debug.exe 只要键入 q 就可以退出程序
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-8-20 12:19:26 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2019-8-20 14:35 编辑
                MOV DI,0
                POP BX            ; 这一句破坏了堆栈平衡
                MOV AL,DS:10H[BX] ; 取出颜色

      改成下面这样就可以了:
                MOV DI,0
                XOR BX,BX         ; 让 BX 指向数据段开头位置(0 偏移)
                MOV AL,DS:10H[BX] ; 取出颜色

      由于堆栈平衡被破坏,在循环中,ES 的值不正确,导致无法正常显示信息。

      楼主可以参考一下我修改的代码:
ASSUME CS:CODE , DS:DATA

DATA SEGMENT PARA PUBLIC 'DATA'
 MESSAGE DB 'welcome to masm!' , 00h
  COLOR DB 02h
DATA ENDS

STACK SEGMENT STACK
        DW 8 DUP(0)
STACK ENDS

CODE SEGMENT PARA PUBLIC 'CODE'
MAIN PROC FAR
                MOV AX,DATA
                MOV DS,AX              ;DS为数据源
                MOV AX,0B872H
                MOV CX,3
                CLD
            M1: MOV ES,AX
                PUSH AX
                MOV SI,OFFSET MESSAGE
                XOR DI,DI
            M2: LODSB
                OR AL,AL
                JZ M3
                STOSB
                MOV AL,COLOR
                STOSB
                JMP M2                 
            M3: POP AX
                ADD AX,0AH
                LOOP M1
                XOR AX,AX
                INT 016H
                MOV AX,4C00H
                INT 21H                
MAIN ENDP
CODE ENDS
END MAIN

    任何时候,想退出 debug.exe 只要键入 q 就可以退出程序
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-20 14:48:19 | 显示全部楼层
jackz007 发表于 2019-8-20 12:19
改成下面这样就可以了:


谢谢。
不用“XOR BX,BX ”,我直接把“POP BX”砍掉,也能正常运行了(因为代码开头的时候已经将BX置0了)

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-20 15:01:41 | 显示全部楼层
jackz007 发表于 2019-8-20 12:19
改成下面这样就可以了:

这个题还有个地方不是很懂:
运行exe时,可以正确的出现结果了,为什么debug单步调试时,用“-D B872:0”直接查看目标内存单元,却看不到预期的数据呢???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-20 15:15:17 | 显示全部楼层
本帖最后由 jackz007 于 2019-8-20 15:18 编辑
徒手拆高达 发表于 2019-8-20 15:01
这个题还有个地方不是很懂:
运行exe时,可以正确的出现结果了,为什么debug单步调试时,用“-D B872:0 ...


        因为你要看的是显存的内容,是会和屏显的内容同步改变的。

        也可以说,不用去看这个地址的内容,因为,此刻,这些内容正在屏幕上。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-20 15:30:29 | 显示全部楼层
jackz007 发表于 2019-8-20 15:15
因为你要看的是显存的内容,是会和屏显的内容同步改变的。

        也可以说,不用去看这个 ...

原来如此 非常感谢。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-24 05:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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