2013-04-27 24 views
0

請幫我找到在這段代碼中的錯誤。它應該清理屏幕,但它不能正常工作。錯誤的代碼清理屏幕x86的DOS

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 

回答

1

mov ah,0int 10h是用於更改視頻模式的BIOS調用。模式編號在al(如您的代碼:mov al,131)中給出。如果設置了最高位al,則IBM標準模式不會清除屏幕(請參閱Ralf Brown's Interrupt List)。您設置了最高位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的小端體系結構中,寫入一個字(16位,在這種情況下爲ax),使得低字節(低8位,在這種情況下爲al)進入第一字節(這裏是偶數字節),並且高字節(高8位,在這種情況下爲ah)進入第二個字節(這裏是奇數字節)。所以你的字符字節變成屬性字節,反之亦然。

這裏的校正碼(組裝至少與NASM或YASM):

 
[bits 16] 

org 100h  ; .com executable 

mov ax,3 
int 10h  ; set 80x25 text mode 

push word 0b800h 
pop es  ; video memory segment for text modes is 0b800h 

mov al,' ' ; fill with space. 
mov ah,0cah ; blinking bright green on red background. 

; the 2 mov instructions above can be replaced with: mov ax,(256*0cah+' ') 

xor di,di ; di = 0 

mov cx,25*80 ; number of characters. 

fill_vram_loop: 
     mov [es:di],ax ; store attributes and ASCII code into video RAM. 
     add di,2  ; next character. 
     loop fill_vram_loop 

int 20h  ; mov ax,4C00h; int 21h also works on newer DOSes. 
+0

thax你非常:) – 2013-04-28 21:41:13

+0

@MohammadDwekat不客氣。請將我的答案標記爲已接受的答案,如果它解決了您的問題。 – nrz 2013-04-28 21:46:12

+0

我希望,但網站給我這個消息「投票需要15聲望」@nrz – 2013-04-28 21:49:07

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」 的操作碼在偏移0我們的PSP和adiitional DOS推的內部在我們的* .com應用程序將被執行之前,在我們的棧上有一個零字。提示:最後,我們必須確保我們的堆棧指針沒有損壞,並且我們的coedesegment沒有改變。

德克