이것은 간단한 16 색 BMP를 DOS로 인쇄하기위한 거친 작업입니다. 이것으로 땜질하는 동안 나는 예기치 않은 오류를 발견했기 때문에 정보를 찾을 수 없었습니다.DOS에서 잘못된 값으로 DX 값을 저장합니다.
line_len을 dx으로 이동하는 줄이 주석 처리되거나 dx가 ax로 대체 될 때 문제의 오류가 사라집니다. (정확한 숫자는 변경, 비록 자연 가정으로)
new_line:
mov dx,[line_len] ;;restock on pixels
sub cx,[line_pad_len] ;;decrement cx by the padlen -1 to skip the padding.
add bx,[line_pad_len] ;;increment read address.
inc bx
loop process_loop ;;return to loop and decrement.
오류는
Invalid Opcode at EEAf 2D00 0217 0000 [... rest is zeroes ]
Invalid Opcode at 0013 0000 0202 0000 0013 0100 0002 0001 756E 6573 0864 0607 0405
Invalid Opcode at FECB 118A 0202 118A 189C 0000 4D4E 0000 [...]
과 이후는 FreeDOS에를 중단 읽어 보시기 바랍니다. 이것에 대한 디버그를 실행하고 단계별로 살펴보면, 마지막으로 읽을 수있는 것은 (첫 번째) LOOP 니모닉이며, 여기서 normaly은 루프의 첫 번째 변경으로 건너 뜁니다. (내가 알 수있는 한)
불행히도, 나는 DOS와 Assembly 모두에서 초보자이며이 정보로 해결책을 찾을 수 없었다. DX를 AX로 대체하면 오류가 사라지 긴하지만이 오류가 나타나는 이유를 이해하려고 노력할 것입니다. 그래서 앞으로는 피할 수 있습니다.
아래의 bmp-> bin 변환기의 전체 소스입니다.
org 100h
segment .code
mov ax,3d00h ;;OPEN FILE WITH 00 ACCESS. (READ ONLY)
mov dx,filename
int 21h
jc exit ;;C FLAG MEANS ERROR.
mov bx,ax ;;GET FILE HANDLE
mov ax,3f00h ;;read file.
mov cx,400h ;;1024byte buffer available.
mov dx,file_buffer ;;address to the buffer.
int 21h
jc exit ;;C etc.
mov cx,ax ;;Move read bytes into cx.
mov ax,3e00h ;;close file
int 21h
jc exit
;;confirm_file:
cmp word [file_buffer],4d42h
jnz exit_bmp ;;THIS IS NOT A BMP FILE.
mov dx,00h
mov ax, word [file_buffer+0022h]
div word [file_buffer+0016h]
dec ax
mov [line_pad_len],ax
mov dx, word [file_buffer+0012h] ;;get width of image in pixels.
cmp dx,0050h ;;check if it's too wide for our screen.
;;jmp if it is.
mov [line_len],dx
mov bx, word [file_buffer+000ah] ;;get offset of bmp array.
mov cx, word [file_buffer+0022h] ;;get size of pixel array + padding
process_loop: ;;WE WANT 16 COLOUR BMP. 2PX/BYTE. LEFTMOST PX MOST SIGNIFICANT NIBBLE.
mov al,[file_buffer+bx] ;;GET FIRST BYTE OF PIXEL ARRAY.
inc bx ;;INCREMET OUR FILE READ LOCATION.
dec dx
jbe new_line ;;if we are out of line, skip back.
mov ah,al ;;copy al into ah for safekeeping
shr ah,04h ;;ah shifted left 4bit. high nibble should be 0
and al,0fh ;;high nibble zeroed.
;;WRITE NEW DATA TO BUFFER. (STILL UPSIDE DOWN)
mov [outp_buffer+di],ah ;;write ax
inc di
mov [outp_buffer+di],al ;;write al
inc di
loop process_loop ;;DECREMENT CX LOOP
jmp write_file
new_line:
mov dx,[line_len] ;;restock on pixels
sub cx,[line_pad_len] ;;decrement cx by the padlen -1 to skip the padding.
add bx,[line_pad_len] ;;increment read address.
inc bx
loop process_loop ;;return to loop and decrement.
write_file: ;;WARNING! THIS WILL DESTROY THE FILE IT WRITES TO.
mov ah,3ch ;;CREAT FILE
mov dx,newfile ;;PTR TO FILENAME
mov cx,0000h ;;FLAGS
int 21h
jc exit
mov bx,ax ;;file handle.
mov ah,40h ;;write to our file
mov cx,di ;;di should have bytes written.
mov dx,outp_buffer ;;get pointer to output buffer.
int 21h
jc exit ;;did we fail?
mov ah,3eh ;;Close our file.
int 21h
exit:
mov ah,4ch
int 21h
exit_bmp:
mov ax,4c66h
int 21h
segment .data
filename: db "IN.BMP",00h
line_len: dw 0000h
newfile: db "OUT.BIN",00h
line_pad_len: dw 0000h
segment .bss
file_buffer: resb 1024 ;;FIGURE OUT BETTER WAY TO DO LEN.
outp_buffer: resb 1024 ;;FIGURE OUT BETTER STUFF.
IN.BMP의 크기는 무엇입니까? 나는 128x96 픽셀 인 16 색 비트 맵을 사용했고, 8190 바이트의 출력 파일을 얻었다. 오류가보고되지 않았습니다 (DOSBox 사용). – Michael
내 IN.BMP는 80x32입니다. 다른 크기로 이것을 읽었을 때 나는 그것을 다시 테스트했고 실패하지 않았습니다. (결과 bin이 올바르지 않습니다. bmp와 bottom-to-top 순서로 패딩을 뺀 것입니다.) 그렇지만 너비 80은 오류를 재현하는 것 같습니다. – Vivix