TASM 8086输入指定字符后无法显示图片,调试异常求助
8086 TASM 图片切换功能故障排查
我编写了如下TASM 8086代码,希望实现用户输入指定字符后切换显示图片的功能:
IDEAL MODEL small STACK 100h p386 DATASEG filename1 db 'picture1.bmp',0 filename2 db 'instructions.bmp',0 filehandle1 dw ? filehandle2 dw ? Header1 db 54 dup (0) Header2 db 54 dup (0) Palette1 db 256*4 dup (0) Palette2 db 256*4 dup (0) ScrLine1 db 320 dup (0) ScrLine2 db 320 dup (0) ErrorMsg1 db 'Error', 13, 10 ,'$' ErrorMsg2 db 'Error', 13, 10 ,'$' CODESEG ; The following procedures are picture related ;------------------------------------------------------------------- ;Prints the bmp file provided ;IN: ax - img offset, imgHeight (dw), imgWidth (dw), printAdd (dw) ;OUT: printed bmp file proc OpenFile1 ; Open file mov ah, 3Dh xor al, al mov dx, offset filename1 int 21h jc openerror1 mov [filehandle1], ax ret openerror1 : mov dx, offset ErrorMsg1 mov ah, 9h int 21h ret endp OpenFile1 proc ReadHeader1 ; Read BMP file header, 54 bytes mov ah,3fh mov bx, [filehandle1] mov cx,54 mov dx,offset Header1 int 21h ret endp ReadHeader1 proc ReadPalette1 ; Read BMP file color palette, 256 colors * 4 bytes (400h) mov ah,3fh mov cx,400h mov dx,offset Palette1 int 21h ret endp ReadPalette1 proc CopyPal1 ; 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 Palette1 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 PalLoop1: ; 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 PalLoop1 ret endp CopyPal1 proc CopyBitmap1 ; 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 PrintBMPLoop1 : 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 ScrLine1 int 21h ; Copy one line into video memory cld ; Clear direction flag, for movsb mov cx,320 mov si,offset ScrLine1 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 PrintBMPLoop1 ret endp CopyBitmap1 proc CloseFile1 mov ah,3Eh mov bx,[filehandle1] int 21h ret endp CloseFile1 proc OpenFile2 ; Open file pusha mov ah, 3Dh xor al, al mov dx, offset filename2 int 21h jc openerror2 mov [filehandle2], ax popa ret openerror2 : mov dx, offset ErrorMsg2 mov ah, 9h int 21h popa ret endp OpenFile2 proc ReadHeader2 ; Read BMP file header, 54 bytes mov ah,3fh mov bx, [filehandle2] mov cx,54 mov dx,offset Header2 int 21h ret endp ReadHeader2 proc ReadPalette2 ; Read BMP file color palette, 256 colors * 4 bytes (400h) mov ah,3fh mov cx,400h mov dx,offset Palette2 int 21h ret endp ReadPalette2 proc CopyPal2 ; 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 Palette2 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 PalLoop2: ; 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 PalLoop2 ret endp CopyPal2 proc CopyBitmap2 ; 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 PrintBMPLoop2 : 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 ScrLine2 int 21h ; Copy one line into video memory cld ; Clear direction flag, for movsb mov cx,320 mov si,offset ScrLine2 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 PrintBMPLoop2 ret endp CopyBitmap2 ;--------------------------------------------------------------------------------------- start: mov ax, @data mov ds, ax ; Graphic mode mov ax, 13h int 10h ; Process BMP file call OpenFile1 call ReadHeader1 call ReadPalette1 call CopyPal1 call CopyBitmap1 ; Wait for key press mov ah,1 int 21h cmp al , 'i' call CloseFile1 je function_call ; Back to text mode ;mov ah, 0 ;mov al, 2 ;int 10h jmp continue function_call: call OpenFile2 ; Graphic mode ; Process BMP file call ReadHeader2 call ReadPalette2 call CopyPal2 call CopyBitmap2 ; Wait for key press continue: mov ah,1 int 21h cmp al, 'b' je OpenFile1 ; Back to text mode mov ah, 0 mov al, 2 int 10h exit: mov ax, 4c00h int 21h END start
实际运行时,输入指定字符后程序仅输出Error,无法显示目标图片。调试过程中发现:
- 使用Turbo Debug调试时,al寄存器已获取正确的输入值,程序能进入第二张图片的处理函数,但后续执行出错;
- OpenFile1过程中的
jc openerror1指令在调试器中显示为jb #nameofthefile#openerror。
已尝试网络查找相关解释但未解决问题,恳请协助排查。
内容的提问来源于stack exchange,提问作者ethan fridkin
相关产品推荐
相关产品推荐

