如何在装配图形模式下打印BMP图片文件
How to print BMP photo file in assembly graphics mode
所以我尝试从我在学校的学习书中复制代码来打印一个 bmp 文件,按照提到的方法做了所有事情,它只显示错误消息。
谁能帮我调试?
代码:
IDEAL
MODEL small
STACK 100h
DATASEG
;================================
filename db 'test.bmp',0
filehandle dw ?
Header db 54 dup (0)
Palette db 256*4 dup (0)
ScrLine db 320 dup (0)
ErrorMsg db 'Error', 13, 10,'$'
;================================
CODESEG
;================================
proc OpenFile
; Open file
mov ah, 3Dh
xor al, al
mov dx, offset filename
int 21h
jc openerror
mov [filehandle], ax
ret
openerror:
mov dx, offset ErrorMsg
mov ah, 9h
int 21h
ret
endp OpenFile
proc ReadHeader
; Read BMP file header, 54 bytes
mov ah,3fh
mov bx, [filehandle]
mov cx,54
mov dx,offset Header
int 21h
ret
endp ReadHeader
proc ReadPalette
; Read BMP file color palette, 256 colors * 4 bytes (400h)
mov ah,3fh
mov cx,400h
mov dx,offset Palette
int 21h
ret
endp ReadPalette
proc CopyPal
; Copy the colors palette to the video memory
; The number of the first color should be sent to port 3C8h
; The palette is sent to port 3C9h
mov si,offset Palette
mov cx,256
mov dx,3C8h
mov al,0
; Copy starting color to port 3C8h
out dx,al
; Copy palette itself to port 3C9h
inc dx
PalLoop:
; Note: Colors in a BMP file are saved as BGR values rather than RGB.
mov al,[si+2] ; Get red value.
shr al,2 ; Max. is 255, but video palette maximal
; value is 63. Therefore dividing by 4.
out dx,al ; Send it.
mov al,[si+1] ; Get green value.
shr al,2
out dx,al ; Send it.
mov al,[si] ; Get blue value.
shr al,2
out dx,al ; Send it.
add si,4 ; Point to next color.
; (There is a null chr. after every color.)
loop PalLoop
ret
endp CopyPal
proc CopyBitmap
; BMP graphics are saved upside-down.
; Read the graphic line by line (200 lines in VGA format),
; displaying the lines from bottom to top.
mov ax, 0A000h
mov es, ax
mov cx,200
PrintBMPLoop:
push cx
; di = cx*320, point to the correct screen line
mov di,cx
shl cx,6
shl di,8
add di,cx
; Read one line
mov ah,3fh
mov cx,320
mov dx,offset ScrLine
int 21h
; Copy one line into video memory
cld
; Clear direction flag, for movsb
mov cx,320
mov si,offset ScrLine
rep movsb
; Copy line to the screen
;rep movsb is same as the following code:
;mov es:di, ds:si
;inc si
;inc di
;dec cx
;loop until cx=0
pop cx
loop PrintBMPLoop
ret
endp CopyBitmap
;================================
start:
mov ax, @data
mov ds, ax
;================================
; Graphic mode
mov ax, 13h
int 10h
; Process BMP file
call OpenFile
call ReadHeader
call ReadPalette
call CopyPal
call CopyBitmap
; Wait for key press
mov ah,1
int 21h
; Back to text mode
mov ah, 0
mov al, 2
int 10h
;================================
exit:
mov ax, 4c00h
int 21h
END start
这是全部代码。
您需要合适的 .bmp 文件:
Name: test.bmp
Location: In the current directory
Width: 320
Height: 200
Colors: 256
收下这个(版权归我所有!免费使用!):
右键单击图片并保存图片。使用 Irfanview 之类的工具将其重新格式化为 BMP,并将其重命名为 "test.bmp"。放在你启动程序的目录下。
如果你使用 DOSBox the picture is distorted since DOSBox "translates" the 320*200 video mode Int 10h AH=00h AL=13h
到它自己的屏幕分辨率,默认情况下是 4/3 模式(我猜是 640*480)。更改 dosbox-0.74.conf
中 windowresolution
的值在这里没有效果。 :-(
您照片的高度和宽度需要与您的高度和宽度参数相匹配。我建议将您的照片涂上油漆以检查那里的坐标。我试过了,它对我有用。
所以我尝试从我在学校的学习书中复制代码来打印一个 bmp 文件,按照提到的方法做了所有事情,它只显示错误消息。 谁能帮我调试?
代码:
IDEAL
MODEL small
STACK 100h
DATASEG
;================================
filename db 'test.bmp',0
filehandle dw ?
Header db 54 dup (0)
Palette db 256*4 dup (0)
ScrLine db 320 dup (0)
ErrorMsg db 'Error', 13, 10,'$'
;================================
CODESEG
;================================
proc OpenFile
; Open file
mov ah, 3Dh
xor al, al
mov dx, offset filename
int 21h
jc openerror
mov [filehandle], ax
ret
openerror:
mov dx, offset ErrorMsg
mov ah, 9h
int 21h
ret
endp OpenFile
proc ReadHeader
; Read BMP file header, 54 bytes
mov ah,3fh
mov bx, [filehandle]
mov cx,54
mov dx,offset Header
int 21h
ret
endp ReadHeader
proc ReadPalette
; Read BMP file color palette, 256 colors * 4 bytes (400h)
mov ah,3fh
mov cx,400h
mov dx,offset Palette
int 21h
ret
endp ReadPalette
proc CopyPal
; Copy the colors palette to the video memory
; The number of the first color should be sent to port 3C8h
; The palette is sent to port 3C9h
mov si,offset Palette
mov cx,256
mov dx,3C8h
mov al,0
; Copy starting color to port 3C8h
out dx,al
; Copy palette itself to port 3C9h
inc dx
PalLoop:
; Note: Colors in a BMP file are saved as BGR values rather than RGB.
mov al,[si+2] ; Get red value.
shr al,2 ; Max. is 255, but video palette maximal
; value is 63. Therefore dividing by 4.
out dx,al ; Send it.
mov al,[si+1] ; Get green value.
shr al,2
out dx,al ; Send it.
mov al,[si] ; Get blue value.
shr al,2
out dx,al ; Send it.
add si,4 ; Point to next color.
; (There is a null chr. after every color.)
loop PalLoop
ret
endp CopyPal
proc CopyBitmap
; BMP graphics are saved upside-down.
; Read the graphic line by line (200 lines in VGA format),
; displaying the lines from bottom to top.
mov ax, 0A000h
mov es, ax
mov cx,200
PrintBMPLoop:
push cx
; di = cx*320, point to the correct screen line
mov di,cx
shl cx,6
shl di,8
add di,cx
; Read one line
mov ah,3fh
mov cx,320
mov dx,offset ScrLine
int 21h
; Copy one line into video memory
cld
; Clear direction flag, for movsb
mov cx,320
mov si,offset ScrLine
rep movsb
; Copy line to the screen
;rep movsb is same as the following code:
;mov es:di, ds:si
;inc si
;inc di
;dec cx
;loop until cx=0
pop cx
loop PrintBMPLoop
ret
endp CopyBitmap
;================================
start:
mov ax, @data
mov ds, ax
;================================
; Graphic mode
mov ax, 13h
int 10h
; Process BMP file
call OpenFile
call ReadHeader
call ReadPalette
call CopyPal
call CopyBitmap
; Wait for key press
mov ah,1
int 21h
; Back to text mode
mov ah, 0
mov al, 2
int 10h
;================================
exit:
mov ax, 4c00h
int 21h
END start
这是全部代码。
您需要合适的 .bmp 文件:
Name: test.bmp
Location: In the current directory
Width: 320
Height: 200
Colors: 256
收下这个(版权归我所有!免费使用!):
右键单击图片并保存图片。使用 Irfanview 之类的工具将其重新格式化为 BMP,并将其重命名为 "test.bmp"。放在你启动程序的目录下。
如果你使用 DOSBox the picture is distorted since DOSBox "translates" the 320*200 video mode Int 10h AH=00h AL=13h
到它自己的屏幕分辨率,默认情况下是 4/3 模式(我猜是 640*480)。更改 dosbox-0.74.conf
中 windowresolution
的值在这里没有效果。 :-(
您照片的高度和宽度需要与您的高度和宽度参数相匹配。我建议将您的照片涂上油漆以检查那里的坐标。我试过了,它对我有用。