John_Green
John_Green

Reputation: 25

How to print ASCII array in Assembly?

I'm trying to make a car game in Assembly's graphic mode. For this, I have to print a car to the screen that I could move on the x-axis with the keyboard. I'm trying to print an ASCII array but it doesn't work.

I attach the array and the printing procedure with the problem. I'd be happy if someone will spot the problem.

Thanks for the help!

The problem: While I'm running the program, everything works just fine Until the 'printing car' procedure has to work. It works but instead of printing a car on the screen, it prints lots of dispersed pixels on the same x axis.

car db 0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0          
    db 0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0       
    db 0,0,0,0,0,4,4,4,4,4,4,4,4,0,4,0,4,0,4,4,4,4,4,4,4,4,0,0,0,0,0   
    db 0,0,0,0,4,4,4,4,4,4,4,4,0,4,4,4,4,4,0,4,4,4,4,4,4,4,4,0,0,0,0   
    db 0,0,0,4,4,14,14,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,14,14,4,4,0,0,0
    db 0,0,0,4,14,14,4,4,4,4,4,0,4,4,4,4,4,4,4,0,4,4,4,4,4,14,14,4,0,0,0 
    db 0,0,4,4,14,14,4,4,4,4,0,0,4,4,4,4,4,4,4,0,0,4,4,4,4,14,14,4,4,0,0 
    db 0,0,4,4,14,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,14,4,4,0,0
    db 0,0,4,4,4,4,4,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,4,4,4,4,4,0,0
    db 0,0,4,4,0,4,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,4,0,4,4,0,0
    db 0,0,0,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,0,0
    db 0,0,0,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,0,0
    db 0,0,0,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,0,0
    db 0,0,0,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,0,0,0
    db 0,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,4,4,0
    db 0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,4,4,4
    db 0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0  
    db 0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0
    db 0,0,0,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,0,0,0 
    db 0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0
    db 0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0
    db 0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0
    db 0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0
    db 0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0
    db 0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0 
    db 0,0,4,4,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,4,4,0,0
    db 0,0,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,4,4,0,0
    db 0,0,4,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,0,0
    db 0,0,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,4,4,0,0
    db 0,0,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,4,0,0
    db 0,0,0,4,4,4,4,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,0,0,0
    db 0,0,0,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,4,4,4,4,0,0,0
    db 0,0,0,0,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,4,4,4,4,0,0,0,0
    db 0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0
    db 0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0

Xcar dw 150


proc carP
    push ax
    push bx
    push cx
    push dx
    push si
    push di
    xor si, si
    xor di, di
    mov bx, offset car
    mov cx, [Xcar]
    BLoop:
        cmp [byte ptr bx], 0
        je Pixel
        mov al, [byte ptr bx] 
        mov ah, 0ch
        mov dx, 140
        add cx, si
        int 10h
    Pixel:
        inc bx
        inc si
        cmp si, 34
        jne BLoop
        mov si, 0
        inc cx
        inc di
        cmp di, 34
        jne BLoop

    pop ax
    pop bx
    pop cx
    pop dx
    pop si
    pop di
    ret
endp carP

Upvotes: 2

Views: 542

Answers (1)

Sep Roland
Sep Roland

Reputation: 39166

push ax
push bx
push cx
push dx
push si
push di
...
pop ax
pop bx
pop cx
pop dx
pop si
pop di

1 When you use the stack to preserve registers, you have to pop them in reverse order from how you pushed them!

push ax
 push bx
  push cx
   push dx
    push si
     push di
     ...
     pop di
    pop si
   pop dx
  pop cx
 pop bx
pop ax

2 I've counted for your car data 35 rows with each 31 bytes. This makes a total of 1085 bytes. However your nested loops process 34 x 34 bytes. That's 1156 bytes!

3 Skipping the black pixels might or might not be a good idea. It depends on whether you clear that part of the screen before drawing the car.

3 Because the outer loop uses inc cx instead of reloading with mov cx, [Xcar], you'll get a skewed picture! Is this intentional?

4 Having mov dx, 140 within the inner loop will inevitably put all the pixels on the same Y coordinate. This instruction must go before starting the outer loop and you need to increment the DX register at the completion of the inner loop.

5 Because the add cx, si instruction was within a part of the code that gets skipped for every black color, the X coordinate will not advance like it should.

6 The BIOS.WritePixel function requires a display page parameter in the BH register. Use display page 0. This required shifting a bit with how the registers are used in your code.

The completed code with all the necessary corrections:

    push    ax
    push    bx
    push    cx
    push    dx
    push    si
    push    di
    push    bp

    xor     di, di            ; Vertical counter 0..34 (35)
    mov     dx, 140           ; Topside Y
    mov     si, offset car
    mov     bh, 0             ; Display page 0
    cld                       ; DF=0 so pointer will auto-increment (*)
OuterLoop:
    xor     bp, bp            ; Horizontal counter 0..30 (31)
    mov     cx, [Xcar]        ; Leftside X

InnerLoop:
    lodsb                     ; Fetch data byte plus increment pointer (*)
    cmp     al, 0
    je      SkipPixel
    mov     ah, 0Ch           ; BIOS.WritePixel
    int     10h
SkipPixel:
    inc     cx                ; Next X coordinate
    inc     bp
    cmp     bp, 31            ; 31 bytes per row in DB for the car
    jb      InnerLoop

    inc     dx                ; Next Y coordinate
    inc     di
    cmp     di, 35            ; 35 rows of DB for the car
    jb      OuterLoop

    pop     bp
    pop     di
    pop     si
    pop     dx
    pop     cx
    pop     bx
    pop     ax
    ret

Upvotes: 4

Related Questions