徒手拆高达 发表于 2019-8-20 10:54:27

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

代码与小甲鱼视频中的代码略有差异。代码如下
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: ;每次循环,从DS:中取出数据,存储到AL中
                MOV ES:,AL ;每次循环,将AL中的数据放入到ES:中
                INC SI
                ADD DI,2
                LOOP S1
                               
                MOV DI,0
                POP BX
                MOV AL,DS:10H ;取出颜色
                MOV CX,10H
S2:
                MOV ES:1,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:”可以读取目标数据存入AL,但是“MOV ES:,AL ”无法将AL写入到ES:(初次写入位置B8720H),这是为啥呢。。。。求指教。

jackz007 发表于 2019-8-20 12:19:26

本帖最后由 jackz007 于 2019-8-20 14:35 编辑

                MOV DI,0
                POP BX            ; 这一句破坏了堆栈平衡
                MOV AL,DS:10H ; 取出颜色

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

      由于堆栈平衡被破坏,在循环中,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 就可以退出程序

徒手拆高达 发表于 2019-8-20 14:48:19

jackz007 发表于 2019-8-20 12:19
改成下面这样就可以了:




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

徒手拆高达 发表于 2019-8-20 15:01:41

jackz007 发表于 2019-8-20 12:19
改成下面这样就可以了:




这个题还有个地方不是很懂:
运行exe时,可以正确的出现结果了,为什么debug单步调试时,用“-D B872:0”直接查看目标内存单元,却看不到预期的数据呢???

jackz007 发表于 2019-8-20 15:15:17

本帖最后由 jackz007 于 2019-8-20 15:18 编辑

徒手拆高达 发表于 2019-8-20 15:01
这个题还有个地方不是很懂:
运行exe时,可以正确的出现结果了,为什么debug单步调试时,用“-D B872:0 ...

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

      也可以说,不用去看这个地址的内容,因为,此刻,这些内容正在屏幕上。

徒手拆高达 发表于 2019-8-20 15:30:29

jackz007 发表于 2019-8-20 15:15
因为你要看的是显存的内容,是会和屏显的内容同步改变的。

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

原来如此 非常感谢。{:5_108:}
页: [1]
查看完整版本: 实验九,“MOV ES:[DI],AL”无法写入数据