I'm a university student and I can't figure out where my mistake is. Here's my assignment to write in x86 assembly language.(I wrote on an INTEL syntax, I use DosBOX to run it).
I've asked a similar question before.
Here's the task.
Fill page 0 of the video memory with any text. In the first line of the screen, display 16 NUL characters (ASCII code 0) with different values of the background attribute (the highest tetrad of the symbol attribute). Press the left button in the first line to select and store the selected color. When the cursor is placed on any character of the remaining lines of the screen, the color of the character will change to the selected one by pressing the left button.
BUT now I face another problem. When I click on the symbol, it does not change color to the selected one. To be honest I'm already confused and do not know how to fix it.
.386
Data segment use16
ColorOne db 2fh
ColorMain db 0fh
sym db 100
style db ?
Data ends
Code segment use16
assume cs:Code, ds:Data
start:
mov ax, DATA
mov ds, ax
mov ax, 0B800h
mov es, ax
mov ax, 3 ; 80x35
int 10h
mov bx, 0
xor di, di
; screen fill
loop1:
add di, bx
imul di, 2
mov ah, ColorOne
mov al, 0
stosw
add ColorOne, 10h
inc bx
xor di, di
cmp bx, 16
jl loop1
mov bx, 1
loop2:
mov cx, 0
loop3:
add di, bx
imul di, 80
add di, cx
imul di, 2
mov ah, ColorMain
mov al, sym
stosw
inc cx
xor di, di
cmp cx, 80
jl loop3
inc bx
inc sym
cmp bx, 25
jl loop2
;---------------------------------------------------------
mov ax, 1 ; show cursor
int 33h
mov ax, 0ch
mov cx, 11b ; move and press left button
push es ; save segment status
push cs
pop es
lea dx, prmaus ; set the offset of the event processing procedure from the mouse in the code segment
int 33h ; registration of the address and conditions of the call
pop es
mov ah, 01h ; wait
int 21h ; pause
xor cx,cx ; disconect mouse
mov ax,0ch
int 33h
mov ax, 3 ; clean screen
int 10h
mov ax, 4c00h ; exit
int 21h
;----------------------------------------------------------
prmaus proc far
; saving the contents of registers ds, es
push ds
push es
pusha
push 0b800h
pop es
push Data
pop ds
; algorithm
to_left_mouse:
cmp ax, 10b
jne to_end
mov ax, 2 ; hide cursor
int 33h
shr cx, 3
shr dx, 3
mov di, dx
imul di, 160
add di, cx
add di, cx
cmp di, 80
jg another_row
first_row:
mov al, es:[di] ; Get the value of the attribute
mov style, al ; Store the color in the style variable
jmp to_end ; Jump to the end of the procedure
another_row:
mov al, style
mov es:[di], al ; Change the value of the attribute
to_end:
mov ax, 1 ; show cursor
int 33h
popa
pop es
pop ds
retf
prmaus endp
Code ends
end start
It is expected that when you put the cursor on the color selects a color, then when you put the cursor on the symbol, it changes color to the selected
At a quick glance I see next errors:
cmp di, 80 jg another_row
The DI register has an address in the text video memory. A single line comprises 160 bytes. You need to compare to 160 like in:
cmp di, 160
jnb another_row
Building on the knowledge that DX holds the row index [0,24], checking for the first row is best done using:
test dx, dx
jnz another_row
mov al, es:[di] ; Get the value of the attribute mov es:[di], al ; Change the value of the attribute
This is not what I wrote in my previous answer! The attribute is at es:[di+1]
. The +1
is very important. You are erroneously retrieving and overwriting the ASCII field.