Search code examples
assemblyx86dosx86-16

Drawing lines in assembly language


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

Solution

  • 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).