assembly 如何将256色位图图像转换为DB格式?

8xiog9wr  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(142)

我正在寻找一种方法来转换256色位图图像到ASM文件,其中包含许多DB命令与字节序列。
我创建了一个256色、分辨率为320x200像素的位图。

我想一个程序,让我指定的位图转换。必须将图像转换为.ASM文件,转换为emu8086兼容的十进制或二进制或十六进制格式的字节字符串。
然后,我将加载转换后的文件(.ASM)到内存中(使用include命令),并通过为屏幕上的像素着色来读取每个字节。
生成的.ASM文件示例:

DB 10,15,24,32,...
DB 00AH,00FH,018H,020H,...
DB 00001010B,00001111B,00010010B,00100000B,...

我试图创建一个程序,读取.TXT文件并打印内容,但它没有工作。
我试图建立这个程序来转换位图文件在一个文本文件与。ASM扩展名和一个字符串的字节内。

org 100h
JMP START

INPUT DB "TEST.TXT", 0
OUTPUT DB "TEST.DB", 0
ERROR DB "FILE NOT FOUND$"

HANDLE DW ?
BUFFER DB 4 DUP(' ') ; i had found this command on internet but i don't know why i need to include it

START:

MOV AH,00H          ; set video mode
MOV AL,03H          ; 80x25 chars with 16 colors
INT 10H             ; Interrupt

; --------------------
; Read the bitmap file
; --------------------

MOV AH,3DH              ; Open the file
MOV AL,0                ; Only in read mode
MOV DX,OFFSET INPUT     ; TEST.TXT
INT 21H                 ; interrupt
JC STOP                 ; If the file not exist print an error

MOV HANDLE,AX           ; i had found this command on internet but i don't know why i need to include it

MOV BX,HANDLE
MOV DX,OFFSET BUFFER
MOV CX,0042H            ; read 42 bytes
MOV AH,3FH         
INT 21H

MOV HANDLE,0000H

READ:

MOV DL,[0124H]      ; print first byte of txt file from 0124H memory location
MOV AH,02H          ; print a char on screen
INT 21H             ; Interrupt

; close the file

MOV AH,3EH
MOV BX,HANDLE
INT 21H

JMP EXIT

STOP:
MOV DX,OFFSET ERROR
MOV AH,9
INT 21H

EXIT:
ret

感谢所有回答我的人。

dgsult0t

dgsult0t1#

BUFFER DB 4 DUP(' ') ; i had found this command on internet but i don't know why i need to include it

您需要它,因为您将需要使用一些内存缓冲区,您可以在其中存储(部分)用作输入的.BMP文件。
这个特殊的db 4 dup(' ')所做的是保留一小部分4字节的内存作为 BUFFER(从标签名称来看)。值4在这里很重要,因为它限制了您可以使用此缓冲区执行的操作。你的程序读取了0042 H字节,这比缓冲区可以容纳的要多得多。缓冲区溢出,对程序的影响将是灾难性的!

MOV CX,0042H            ; read 42 bytes

希望这里有一个错字,但要知道0042 H和42字节不一样。它是66字节。

MOV HANDLE,AX           ; i had found this command on internet but i don't know why i need to include it

当打开一个文件时(就像你做的那样),DOS返回一个已打开文件的句柄。这是一个数字,DOS可以在所有后续的交互中识别该文件,您计划进行有关此文件。使用一个单词大小的数字要比不断地通过文件名(也可能包括路径)引用文件容易得多。

MOV HANDLE,0000H
...
MOV AH,3EH
MOV BX,HANDLE
INT 21H

重置 HANDLE 变量后,就不应该再在CloseFile操作中使用它。

MOV DL,[0124H]      ; print first byte of txt file from 0124H memory location

汇编者最清楚!使用缓冲区的名称并写入:mov dl, BUFFER。使用emu 8086时,方括号是可选的。
我编写了一个演示程序,它将一个320 x200 256色的.BMP文件转换为一个充满db行的.TXT文件。这是你最终需要的一个很好的起点。这只是一个开始,因为:

  • 您需要提示用户提供文件名
  • 您需要包括适当的错误消息
  • 你需要 * 不 * 跳过文件头,而是解析它们,这样你就可以:
  • 验证.BMP文件是否为有效的位图文件
  • 支持尺寸不是320 x 200位图
  • 支持具有替代方向位图
  • 你需要 * 不 * 跳过颜色表,而是使用它,这样你就可以按照预期的颜色来显示图片

该程序在一台真正的MS-DOS机器上进行了测试。它跑得非常快,但我不知道有多快/慢emu 8086可以运行这个.

ORG     256

    mov     dx, OFFSET TxtF
    xor     cx, cx
    mov     ah, 3Ch     ; DOS.CreateFile
    int     21h         ; -> AX CF
    jc      Exit
    mov     TxtH, ax

    mov     dx, OFFSET BmpF
    mov     ax, 3D00h   ; DOS.OpenFile
    int     21h         ; -> AX CF
    jc      Exit
    mov     BmpH, ax

    mov     dx, 14+40+1024  ; Skip .BMP headers and color table
    xor     cx, cx
    mov     bx, ax
    mov     ax, 4200h   ; DOS.SeekFile
    int     21h         ; -> DX:AX CF
    jc      Exit

    mov     bp, (320*200)/16
OuterLoop:
    mov     dx, OFFSET BmpS
    mov     cx, 16
    mov     bx, BmpH
    mov     ah, 3Fh     ; DOS.ReadFile
    int     21h         ; -> AX CF
    jc      Exit
    cmp     ax, cx
    jne     Exit

    mov     di, OFFSET TxtS+3
    mov     si, OFFSET BmpS
InnerLoop:
    lodsb
    aam     100
    add     ah, '0'
    mov     [di], ah
    aam
    add     ax, '00'
    xchg    al, ah
    mov     [di+1], ax
    add     di, 4
    loop    InnerLoop

    mov     dx, OFFSET TxtS
    mov     cx, 68
    mov     bx, TxtH
    mov     ah, 40h     ; DOS.WriteFile
    int     21h         ; -> AX CF
    jc      Exit

    dec     bp
    jnz     OuterLoop

    mov     bx, BmpH
    mov     ah, 3Eh     ; DOS.CloseFile
    int     21h         ; -> AX CF

    mov     bx, TxtH
    mov     ah, 3Eh     ; DOS.CloseFile
    int     21h         ; -> AX CF

Exit:
    mov     ax, 4C00h   ; DOS.Terminate
    int     21h
; ------------------------------
    ALIGN   2
BmpS    db  16 dup 0
TxtS    db  'db ???', 15 dup (',???'), 13, 10
BmpH    dw  0
TxtH    dw  0
BmpF    db  'EXAMPO4.BMP', 0    ; 65078 bytes
TxtF    db  'EXAMPO4.TXT', 0    ; 272000 bytes

我的输出看起来像什么:

db 000,003,000,017,000,000,000,000,000,000,000,012,151,177,113,087
db 125,151,151,151,140,151,175,158,183,189,245,246,216,244,224,226
db 165,164,148,132,125,087,062,076,115,103,069,066,048,158,097,001
db 059,000,091,091,005,012,000,000,000,011,029,106,024,005,048,062
db 224,212,204,212,183,189,062,214,184,196,160,237,125,162,180,190
db 000,003,000,017,000,000,000,000,000,000,000,012,151,177,113,087
db 125,151,151,151,140,151,175,158,183,189,245,246,216,244,224,226
db 165,164,148,132,125,087,062,076,115,103,069,066,048,158,097,001
db 059,000,091,091,005,012,000,000,000,011,029,106,024,005,048,062
db 224,212,204,212,183,189,062,214,184,196,160,237,125,162,180,190
--- 3990 more lines ---

相关问题