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
nrz
  • 10,435
  • 4
  • 39
  • 71
Mohammad Dwekat
  • 3
  • 1
  • 1
  • 4

2 Answers2

1

mov ah,0, int 10h is the BIOS call used to change video mode. The mode number is given in al (as in your code: mov al,131). If the highest bit of al is set, IBM standard modes do not clear the screen (see Ralf Brown's Interrupt List). You have the highest bit of al set and you request from BIOS the video mode 3 (80x25 text). To do the same BIOS call and clean the screen, all you need is:

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

But, if you want to clear the screen in the middle of a real-time program, you don't want to spend time on changing the video mode with a BIOS call if you have already in the right video mode.

Then, assuming that you have already set the video mode (if not, run first the code above), and you want to write something to video memory. In standard text modes even bytes contain the attributes and the odd bytes contain the ASCII code of the character. Attribute bytes define foreground color, background color and blinking. You may want to check my answer to Printing a string without OS.

In your code used to fill the video memory there are some issues. First, you don't set di to 0. I assume you want to fill the video memory with space (based on mov al,' ' in your code). However, you have wrong byte order in ax. x86 is a little-endian architecture. In little-endian architectures such as x86 a word (16 bits, in this case ax) is written so that low byte (low 8 bits, in this case al) gets in the first byte (here the even bytes), and the high byte (high 8 bits, in this case ah) get in the second byte (here the odd bytes). So your intented character byte becomes the attribute byte and vice versa.

Here's the corrected code (assembles at least with NASM or 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.
Community
  • 1
  • 1
nrz
  • 10,435
  • 4
  • 39
  • 71
  • i hope that but the site give me this message"Vote Up requires 15 reputation" @nrz – Mohammad Dwekat Apr 28 '13 at 21:49
  • @MohammadDwekat Accepting an answer means clicking on the "V" shaped form with gray borders (on the left side of the answer), so that it's color changes from white to green. – nrz Apr 28 '13 at 21:53
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 place the opcode of an "int 20h" at the offset 0 inside of our PSP and adiitional DOS push a word with zero on our stack before our *.com-application will be execute. Hint: At last we have to make sure that our stack pointer is not corrupted and our coedesegment is not changed.

Dirk