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
中保留了像素颜色。这只会导致黑色像素!他们在那里,但你看不到他们。
因为这个问题被标记了 x86 你可以使用通用的 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
我的旧代码使用 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
中保留了像素颜色。这只会导致黑色像素!他们在那里,但你看不到他们。
因为这个问题被标记了 x86 你可以使用通用的 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