Kim Strugo
Kim Strugo

Reputation: 33

assembly 8086 space invaders project, int 10h doesnt work

im making a space invaders project to school and im trying to check if the aliens got to the button of the screen. i used the int 10h d (it takes the color of a pixel on the screen) on my code and it stuck every thing, i tried to understand what happened and came to the conclusion that the line "mov ah,0Dh" along with the "int 10h" line makes it stuck. does anybody has any idea what i can do in order to make it work?

(this is the code)

proc checkAliensDown
pusha
push ax

    mov cx,320           ;loop counter
    checkPixel:          
    push cx

        mov bh,0h
        mov cx,[x]
        mov dx,140
        mov ah,0Dh
        int 10h

        ;the output of the int 10h goes into al
        cmp al,10        ;check if the color of the pixel is green
        jne notDown      ;if not jumps to notDown
            
            mov [lost],1     ;if it is green moves to lost 1
            jmp endProc      ;if it found that the pixel is green it jumps to the end of the proc
            
        notDown:
            
        inc [x]             ;increasing x var in order to check all the pixels in the row, if one of them is green the player lost
        
    pop cx
    loop checkPixel

    endProc:

pop ax
popa
ret
endp checkAliensDown

i tried to push and pop ah and it didn't work

Upvotes: 2

Views: 64

Answers (1)

Sep Roland
Sep Roland

Reputation: 39516

The stack gets un-balanced!

Random data on the stack is used as the return address, and that crashes the program.

The push cx right below checkPixel is still on the stack when your code jumps to endProc (in case the green alien got to the bottom of the screen). Simply add a pop cx to remove it:

mov [lost],1     ;if it is green moves to lost 1
pop cx
jmp endProc

Alternatively, use another register to control the loop:

mov SI,320           ;loop counter
checkPixel:
    mov bh,0h
    mov cx,[x]
    mov dx,140
    mov ah,0Dh
    int 10h
    cmp al,10        ;check if the color of the pixel is green
    jne notDown      ;if not jumps to notDown
        
        mov [lost],1     ;if it is green moves to lost 1
        jmp endProc
    notDown:
    inc [x]
dec  SI
jnz  checkPixel
endProc:

Tip: the push ax that follows pusha is quite useless. AX is already preserved through pusha. Same applies to the pop ax right before popa.

i tried to push and pop ah and it didn't work

It is normal not being able to push or pop a byte-sized register. In the stack operates in word-sized chunks.


Your checkAliensDown proc depends on the x variable to contain 0 beforehand. I would suggest you add that to the proc:

proc checkAliensDown
pusha
mov word [x], 0

Bonus

The best solution for this 8086 task where pusha and popa are not valid instructions:

proc checkAliensDown
 push ax
 push bx
 push cx
 push dx

 mov  [lost], 1 ; Guarantees LOST contains a sensible value upon return
 mov  dx, 140   ; Y
 xor  cx, cx    ; X
 mov  bh, 0     ; Page
checkPixel:
 mov  ah, 0Dh   ; BIOS.ReadPixel
 int  10h       ; -> AL
 cmp  al, 10    ; Is it green?
 je   endProc   ; Jump one time, but have the majority case fall through
 inc  cx
 cmp  cx, 320   ; Use CX for both the X coordinate and the loop counter
 jb   checkPixel
 mov  [lost], cl ; CL=0
endProc:

 pop  dx
 pop  cx
 pop  bx
 pop  ax
 ret
endp checkAliensDown

Upvotes: 1

Related Questions