Assembly 如何在汇编中打印ASCII数组?

Assembly 如何在汇编中打印ASCII数组?,assembly,graphics,x86-16,dosbox,Assembly,Graphics,X86 16,Dosbox,我正试图在组装的图形模式下制作一个汽车游戏。 为此,我必须在屏幕上打印一辆汽车,我可以用键盘在x轴上移动。 我正在尝试打印ASCII数组,但它不起作用 我将阵列和打印过程与问题联系起来。如果有人能发现这个问题,我会很高兴的 谢谢你的帮助 问题是: 当我运行程序时,一切都正常,直到“打印汽车”程序开始工作。它可以工作,但不是在屏幕上打印汽车,而是在同一个x轴上打印许多分散的像素 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

我正试图在组装的图形模式下制作一个汽车游戏。 为此,我必须在屏幕上打印一辆汽车,我可以用键盘在x轴上移动。 我正在尝试打印ASCII数组,但它不起作用

我将阵列和打印过程与问题联系起来。如果有人能发现这个问题,我会很高兴的

谢谢你的帮助

问题是: 当我运行程序时,一切都正常,直到“打印汽车”程序开始工作。它可以工作,但不是在屏幕上打印汽车,而是在同一个x轴上打印许多分散的像素

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
1当您使用堆栈保存寄存器时,您必须
pop
按与
push
相反的顺序保存它们

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我已经为您的汽车数据计算了35行,每行31字节。这总共是1085字节。但是,嵌套循环处理34 x 34字节。这是1156字节

3跳过黑色像素可能是个好主意,也可能不是个好主意。这取决于在绘制汽车之前是否清除屏幕的该部分

3因为外循环使用
inc-cx
而不是使用
mov-cx、[Xcar]
重新加载,所以您会得到一张扭曲的图片!这是故意的吗

4在内环中具有
mov dx,140
将不可避免地将所有像素置于相同的Y坐标上。此指令必须在启动外循环之前执行,并且您需要在完成内循环时增加
DX
寄存器

5由于
add cx,si
指令位于每种黑色都会被跳过的代码部分内,因此X坐标不会像它应该的那样前进

6BIOS.WritePixel函数需要
BH
寄存器中的显示页面参数。使用显示页面0。这需要根据寄存器在代码中的使用方式进行一点移位

完成的代码以及所有必要的更正:

    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

你认为mov dx,140的作用是什么?注释你的代码,特别是如果你想让别人帮忙的话。学习使用调试器。什么是gfx模式?文本模式3或gfx 320x200x8bit或什么?VGA/VESA?看看这些:还有。也完全同意Jester对你的代码的评论,因为当你在一段时间后回到你的代码时,你将不知道它是做什么和如何做的。对我们来说,它只是外来代码,没有任何注释和上下文,很难阅读/解读,所以我们大多数人只是忽略了它,因此回答率很低。。。
    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