汇编(TASM)通过写入内存来绘制像素

时间:2017-05-19 10:23:31

标签: assembly graphics x86 tasm

我的旧代码在模式13h中用int 10h打印了一行。我试图将它从使用int 10h更改为在内存中写入但由于某种原因它不起作用。我不熟悉写在内存中所以我无法猜出是什么问题。

这是新代码:

proc PrintLine
;prints a line
;1.length 
;2.colour
;3.x
;4.y
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push si
mov cx,[bp+10];leangth
mov dx,[bp+4];y
mov al,[bp+8];colour
mov si,[bp+6];x
xor bx,bx
pl:
    push si
    push dx
    push ax
    call PrintPixel
loop pl
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 8
endp PrintLine
proc PrintPixel
;print a pixel through writing into memory
;input:
;1.x
;2.y
;3.colour
;output:
;none
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push di
mov ax,0A000h
mov es,ax
mov ax,[bp+6];y
mov bx,[bp+8];x
mov dl,[bp+4];colour
mov cx,320
mul cx;each line is 320 pixles ax is the number of lines
add ax,bx;bx is the place on the line
mov di,ax
mov [es:di],dl
mov ax, @data  
mov ds, ax
pop di
pop dx
pop cx
pop bx
pop ax
pop bp
ret 6
endp PrintPixel

这是包含int 10h的旧代码:

proc PrintLine
;prints a line
;1.length 
;2.colour
;3.x
;4.y
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push si
mov cx,[bp+10];leangth
mov dx,[bp+4];y
mov al,[bp+8];colour
mov si,[bp+6];x
mov ah,0ch
xor bx,bx
pl:
    push cx
    mov cx,si
    int 10h
    inc si
    pop cx  
loop pl
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 8
endp PrintLine

1 个答案:

答案 0 :(得分:2)

您的 PrintPixel 程序有两个重要问题。

  • 虽然您保留了很多寄存器,但您还使用了根本不保留的ES段寄存器!为什么然后重新初始化DS段寄存器是一个谜。

  • 由于您使用mul cx计算了视频偏移地址,因此您在DX:AX中获得了dword产品,但您保留了DL中的像素颜色。这只会导致黑色像素!他们在那里,但你无法看到它们。

由于此问题已标记为,您可以使用多功能imul指令:

push bp
mov  bp, sp
push ax
push bx
push ds
mov  ax, 0A000h
mov  ds, ax
mov  bx, 320      ; Bytes per line in mode 13h
imul bx, [bp+6]   ; y
add  bx, [bp+8]   ; x
mov  al, [bp+4]   ; colour
mov  [bx], al     <-- No need for any segment override prefix!
pop  ds
pop  bx
pop  ax
pop  bp
ret  6

看看它变得多清洁和缩短了?

如果不再使用BIOS WritePixel ,您还应该清理 PrintLine 程序。它不再需要,例如xor bx, bx 您是否知道可以直接推送内存操作数?这样做,您将保存很多指令!

 push bp
 mov  bp, sp
 push cx
 mov  cx, [bp+10]       ; length
pl:
 push word ptr [bp+6]   ; x
 push word ptr [bp+4]   ; y
 push word ptr [bp+8]   ; colour
 call PrintPixel
 loop pl
 pop  cx
 pop  bp
 ret  8