I wrote program in assembly language which suspposed to draw 8 horizontal lines. But I have a problem. My 5th line doesn't show. Every line should have length 320 and height 25. In CX I have the end of the line and in BX the beginning of the line. Every line should be red. But the 5th line is black.
The code for drawing the lines look like this:
Draw PROC
MOV ax, 0a000h
MOV ES, AX
MOV BX, CX
ADD CX, 8000
etDraw:
MOV al, 4
MOV ES:[BX], AL
INC BX
CMP BX, CX
JL etDraw
RET
ENDP
Using procedure:
MOV AX, 0f00h
INT 10h
MOV ax, 0013H
int 10h
MOV ah, 0Ch
CALL Draw
CALL Draw
CALL Draw
CALL Draw
CALL Draw
CALL Draw
CALL Draw
CALL Draw
MOV ah, 08h
int 21h
mov ax, 0f00h
int 10h
mov ax, 0003h
int 10h
mov ax, 4c00h
int 21h
The problem is that when you compare addresses in Draw
to see if you've reached the end of your line, you using JL
("Jump Less"), which is a signed comparison. You should be using an unsigned comparison (JB
, "Jump Below") or check for equality with JE
or JZ
.
This only happens on your 5th line because that is where the end address rolls over from a positive to a negative number (when it is considered as a signed number). Specifically,
4 * 8000 = 32000
5 * 8000 = 40000, but with 16 bit signed numbers this will be -25536.
With the 5th line, BX starts as 32000, CX starts as -25536, so you'll get one pixel set and the JL
won't jump (because 32001 > -25536).
Remember that whenever you compare addresses, these should almost always be unsigned comparisons (JB
, JA
).