Assembly (TASM) 通过写入内存绘制像素

Assembly (TASM) plotting pixel through writing in memory

我的旧代码使用 int 10h 在模式 13h 中打印了一行。我试图将其从使用 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

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

  • 虽然你保留了很多寄存器,但是你也用到了根本不保留的ES段寄存器!为什么要重新初始化 DS 段寄存器是个谜。

  • 因为您使用 mul cx 计算视频偏移地址,所以您在 DX:AX 中得到了一个双字积,但是您在 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