0

Please help me to found the error in this code. It should clean the screen but it doesn't work correctly.

include inout.asm
.model small,c
.stack 300h
.486
.data
.code
.startup
        mov ah,0
        mov al,131
        int 10h
        push 0b800h
        pop es
        mov cx,25*80
        mov al,' '
        mov ah ,0cah
    a:  mov es:[di],ax
        add di,2
        loop a
.exit
END
4

2 回答 2

1

mov ah,0,int 10h是用于更改视频模式的 BIOS 调用。模式编号在al(如您的代码中所示:)中给出mov al,131。如果设置了最高位al,IBM 标准模式不会清除屏幕(请参阅Ralf Brown 的中断列表)。您有最高位的al设置,并且您从 BIOS 请求视频模式 3(80x25 文本)。要执行相同的 BIOS 调用并清洁屏幕,您只需要:

mov ax,3    ; ah = 0, al = 3
int 10h

但是,如果您想在实时程序的中间清除屏幕,如果您已经处于正确的视频模式,您不想花时间通过 BIOS 调用更改视频模式。

然后,假设您已经设置了视频模式(如果没有,请先运行上面的代码),并且您想向显存中写入一些内容。在标准文本模式中,偶数字节包含属性,奇数字节包含字符的 ASCII 码。属性字节定义前景色、背景色和闪烁。您可能想查看我对Printing a string without OS 的回答。

在您用于填充视频内存的代码中存在一些问题。首先,您没有设置di为 0。我假设您想用空间填充视频内存(基于mov al,' '您的代码)。但是,您在ax. x86 是一种小端架构。在 x86 等小端架构中,ax写入一个字(在本例中为 16 位),以便低字节(在本例中为低 8 位al)进入第一个字节(此处为偶数字节),而高字节 (高 8 位,在这种情况下ah)进入第二个字节(这里是奇数字节)。因此,您的意图字符字节成为属性字节,反之亦然。

这是更正后的代码(至少使用 NASM 或 YASM 组装):

[位 16]

组织 100h ; .com 可执行文件

移动斧头,3
诠释 10h ; 设置 80x25 文本模式

推字 0b800h
流行音乐; 文本模式的显存段是 0b800h

移动,''; 填充空间。
mov ah,0cah ; 在红色背景上闪烁亮绿色。

; 上面的 2 条 mov 指令可以替换为: mov ax,(256*0cah+' ')

xor di,di ; 迪 = 0

mov cx,25*80 ; 字符数。

fill_vram_loop:
        mov [es:di],ax ; 将属性和 ASCII 码存储到视频 RAM 中。
        添加 di,2 ; 下一个字符。
        循环 fill_vram_loop

诠释 20 小时;移动斧头,4C00h;int 21h 也适用于较新的 DOS。
于 2013-04-27T17:07:31.860 回答
0
; fill_vram_loop:
;        mov [es:di],ax ; store attributes and ASCII code into video RAM.
;        lea di, [di+2]  ; add di,2  ; next character.
;        loop fill_vram_loop

rep stosw

;         int 20h

ret

DOS 将“int 20h”的操作码放置在我们 PSP 内的偏移量 0 处,并且在我们的 *.com 应用程序执行之前,DOS 会在我们的堆栈上压入一个为零的单词。提示:最后我们必须确保我们的堆栈指针没有损坏并且我们的 coedesegment 没有改变。

短剑

于 2013-05-01T21:02:39.807 回答