如何用汇编语言8086打印精灵?

问题描述 投票:0回答:1

我正在尝试用汇编语言8086打印精灵。我已经编写了代码,但它没有显示任何内容。

.model small
.stack 100h

.data
    sprite DB 00h,00h,00h,00h,00h,00h,00h,00h,0Fh,00h,00h,00h,00h,00h,00h     ;  0
        DB 0Fh,0Fh,0Fh,00h,00h,00h,00h,00h,0Fh,0Fh,0Fh,07h,00h,00h,00h     ;  1
        DB 00h,0Fh,0Fh,07h,07h,07h,00h,00h,00h,00h,0Fh,07h,07h,07h,07h     ;  2
        DB 00h,00h,00h,0Fh,0Fh,07h,07h,07h,07h,00h,00h,00h,0Fh,0Fh,07h     ;  3
        DB 07h,07h,07h,00h,00h,00h,0Fh,0Fh,07h,07h,07h,07h,00h,00h,00h     ;  4
        DB 0Fh,0Fh,07h,07h,08h,08h,00h,00h,00h,0Fh,0Fh,07h,07h,08h,08h     ;  5
        DB 00h,00h,00h,00h,0Fh,07h,07h,07h,07h,00h,00h,00h,00h,0Fh,07h     ;  6
        DB 07h,07h,07h,00h,00h,00h,07h,07h,0Fh,07h,07h,07h,00h,00h,07h     ;  7
        DB 07h,07h,07h,0Fh,0Fh,07h,00h,00h,07h,07h,00h,07h,07h,07h,0Fh     ;  8
        DB 00h,00h,07h,07h,00h,07h,07h,07h,07h,00h,00h,00h,00h,00h,07h     ;  9
        DB 07h,07h,07h,00h,00h,00h,00h,00h,07h,07h,07h,07h,00h,00h,00h     ; 10
        DB 00h,00h,00h,07h,07h,07h,00h,00h,00h,00h,00h,00h,07h,07h,00h     ; 11
     counter1 db ?
     counter2 db ?
     bullet_pos_x db 10

.code
main proc
    mov ax, @data
    mov ds, ax

    mov si, 0 
    mov counter1, 0
    mov counter2, 0

    ; Initialize CX and DX for sprite positioning
    mov cx, 100  ; Set initial X position within the screen (between 0 and 319)
    mov dx, 50   ; Set initial Y position within the screen (between 0 and 199)

    drawOuter6:
        drawInner6:
            mov ah, 0ch         ; Set AH to 0Ch for plot pixel function
            mov al, sprite[si]  ; Load pixel color into AL
            int 10h             ; Plot the pixel
            inc cx              ; Increment column counter
            inc counter2        ; Increment inner loop counter
            inc si              ; Move to next pixel in sprite
            cmp counter2, 9     ; Check inner loop counter
            jl drawInner6       ; Repeat inner loop if less than 9 pixels

        mov counter2, 0         ; Reset inner loop counter
        mov cl, bullet_pos_x    ; Load bullet_pos_x into the low byte of CX
        inc dx                  ; Increment row counter
        inc counter1            ; Increment outer loop counter
        cmp counter1, 20        ; Check outer loop counter
        jl drawOuter6           ; Repeat outer loop if less than 20 rows

    end_print:
        ; Exit to DOS
        mov ax, 4C00h
        int 21h

main endp
end main
image assembly graphics x86-16 emu8086
1个回答
0
投票

我已经写了代码,但它没有显示任何内容。

您看不到任何输出,因为您忘记设置图形模式。根据您提到的“(0和319之间)”和“(0和199之间)”,这必须是256色320x200图形模式13h。代码如下:

mov  ax, 0013h  ; AH=00h BIOS function number, AL=13h Mode number
int  10h

将初始化该特定视频模式。

mov cl, bullet_pos_x    ; Load bullet_pos_x into the low byte of CX

您不想让您的精灵占据一个宽度为 9 像素、高度为 20 像素的常规矩形吗?在第一行使用

CX=100
,然后在其他行使用
CX=10
不会让事情保持在一起!可能
bullet_pos_x db 10
的本意是读作
bullet_pos_x db 100
。在下面的解决方案中,我实现了一个更简单的解决方案:由于内部循环已将 CX 提高了 9,因此只需从 CX 中减去 9 即可返回到精灵的左侧。

counter1 db ?
counter2 db ?
bullet_pos_x db 10

只要有可能,最好避免使用基于内存的变量。在您的程序中,您仍然有 3 个未使用的寄存器(BX、DI 和 BP)。在下面的代码中,我将内部计数器放置在 BP 中,将外部计数器放置在 DI 中。我还设置了 BH=0,因为通常 BIOS 期望 BH 包含显示页码。我相信 emu8086 不需要这个但是......

  mov  ax, @data
  mov  ds, ax
  mov  ax, 0013h       ; AH=00h BIOS function number, AL=13h Mode number
  int  10h

  mov  bh, 0           ; Select display page (some BIOSes require this)
  mov  cx, 100         ; Set initial X position
  mov  dx, 50          ; Set initial Y position
  xor  si, si          ; Better than `mov si, 0` but same function 
  mov  di, 20          ; Outer loop counter
drawOuter6:
  mov  bp, 9           ; Inner loop counter
drawInner6:
  mov  al, sprite[si]  ; Load pixel color into AL
  mov  ah, 0Ch         ; Set AH to 0Ch for plot pixel function
  int  10h             ; Plot the pixel
  inc  cx              ; Increment X
  inc  si              ; Move to next pixel in sprite
  dec  bp              ; Check inner loop counter
  jnz  drawInner6      ; Repeat inner loop if less than 9 pixels
  sub  cx, 9
  inc  dx              ; Increment Y
  dec  di              ; Check outer loop counter
  jnz  drawOuter6      ; Repeat outer loop if less than 20 lines

给自己一个机会实际看到屏幕上显示的内容。您可以等待用户按下键盘上的任意键,然后再返回 DOS。大多数时候,将视频模式重置为标准 16 色 80x25 文本模式 03h 就是您想要的:

  mov  ah, 00h         ; BIOS.WaitKeystroke
  int  16h
  mov  ax, 0003h       ; AH=00h BIOS function number, AL=03h Mode number
  int  10h
  mov  ax, 4C00h       ; DOS.Terminate
  int  21h
© www.soinside.com 2019 - 2024. All rights reserved.