使用内联 ASM c++ 显示 640x480 BMP 图像
Posted
技术标签:
【中文标题】使用内联 ASM c++ 显示 640x480 BMP 图像【英文标题】:Show 640x480 BMP image with inline ASM c++ 【发布时间】:2015-06-10 02:04:52 【问题描述】:您好,我正在尝试使用 c++ 中的内联 ASM 显示 640x480 BMP 图像(16 色位图),它必须使用内联 asm,因为它是一项家庭作业。我在汇编代码中有这个代码来做到这一点:
cad db 'Error, file not found, press a key to finish.$'
filename db "C:\image.bmp"
handle dw ?
col dw 0
ren dw 479
col1 dw ?
ren1 dw ?
col2 dw ?
ren2 dw ?
buffer db ?
colo db ?
eti0:
mov ah,3dh
mov al,0
mov dx,offset filename
int 21h
jc err
mov handle,ax
mov cx,118d
eti1:
push cx
mov ah,3fh
mov bx,handle
mov dx,offset buffer
mov cx,1
int 21h
pop cx
loop eti1
mov ah,00h
mov al,18d
int 10h
eti2:
mov ah,3fh
mov bx,handle
mov dx,offset buffer
mov cx,1
int 21h
mov al,buffer
and al,11110000b
ror al,4
mov colo,al
mov ah,0ch
mov al,colo
mov cx,col
mov dx,ren
int 10h
mov al,buffer
and al,00001111b
mov colo,al
inc col
mov ah,0ch
mov al,colo
mov cx,col
mov dx,ren
int 10h
inc col
mov ah,0ch
mov al,colo
mov cx,col
mov dx,ren
int 10h
cmp col,639d
jbe eti2
mov col,0
dec ren
cmp ren,-1
jne eti2
现在将其放入内联 ASM 中,我正在尝试使用下一个代码:
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
#include<dos.h>
#include<stdlib.h>
void main(void)
clrscr();
unsigned char buffer,colo;
unsigned int handle,col=0,ren=479,col1,col2,ren2;
int filename=675892105109971031011104698109112;
asm
mov ah,3dh
mov al,0
mov dx,filename
int 21h
mov handle,ax
mov cx,118d
cout<<"si mino1";
for(int i=118;i>0;i++)
asm
mov ah,3fh
mov bx,handle
mov dx,offset buffer
mov cx,1
int 21h
asm
mov ah,00h
mov al,18d
int 10h
cout<<"si mino2";
eti2:
asm
mov ah,3fh
mov bx,handle
mov dx,offset buffer
mov cx,1
int 21h
mov al,buffer
and al,11110000b
ror al,4
mov colo,al
mov ah,0ch
mov al,colo
mov cx,col
mov dx,ren
int 10h
mov al,buffer
and al,00001111b
mov colo,al
inc col
mov ah,0ch
mov al,colo
mov cx,col
mov dx,ren
int 10h
inc col
mov ah,0ch
mov al,colo
mov cx,col
mov dx,ren
int 10h
cmp col,639d
jbe eti2
mov col,0
dec ren
cmp ren,-1
jne eti2
cout<<"si mino3";
getch();
代码到达第一个cout,然后进入无限循环。
【问题讨论】:
为什么filename
是int
?此外,675892105109971031011104698109112
太大,无法放入 int
。
当然,即使合适,675892105109971031011104698109112
也不与"C:\image.bmp"
相同,就像6566
与@987654330 不同一样@.
【参考方案1】:
你真的是指下面这行代码吗:
for(int i=118;i>0;i++)
这会将i
初始化为118,并且每次迭代都加1。它只会变得更大(直到i
溢出)。循环是否应该继续的测试是i > 0
,它将始终为真(直到i
溢出)。
您确定您处于无限循环中吗?也许很多很多int 21h
只需要非常非常长的时间。
【讨论】:
我没有意识到这一点,我将其更改为for(int i=118;i>0;i--)
并在文件名 int 的末尾添加一个零:int filename=6758921051099710310111046981091120;
,现在我得到一个绿屏:link
【参考方案2】:
我想出了如何使用下一个代码显示 640x200 16 色 BMP:
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// << DISPLAY 4-Bit BMP (16 colors) >>
// This program shows how to display a 16 color bitmap.
// I am not using palettes for bmp,hence all default 16 colors are used.
// If you know BMP structure you can try to add palettes.
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#include <alloc.h>
#include <conio.h>
#include <graphics.h>
#include <stdio.h>
#include <stdlib.h>
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#define UL unsigned long
#define UI unsigned int
#define UC unsigned char
//+-+-+-+-+-+-+-+-+-+-+-+-+-+< BMP Structures >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
typedef struct
char Type[2];
UL Size;
UI R1;
UI R2;
UL OffSet;
BMP1;
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
typedef struct
UL headsize;
UL Hlen;
UL Vlen;
UI planes;
UI BPP;
UL Method;
UL BmpSize;
UL HRes;
UL VRes;
UL Colors;
UL IColors;
BMP2;
//+-+-+-+-+-+-+-+-+-+-+-+-+-< Display BMP >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
int ShowBMP(int x, int y, char* FileName)
int b,a;
BMP1 Obj1;
BMP2 Obj2;
UC * Holder;
int in=0;
UC c=0;
FILE * fp;
fp = fopen(FileName,"rb");
if(fp==NULL)
return 0;
fread(&Obj1, sizeof(Obj1), 1, fp);
fread(&Obj2, sizeof(Obj2), 1, fp);
if(Obj2.BPP!=4) // This isn't a 16 color bmp we can read;
fclose(fp);
return 0;
;
fseek(fp,Obj1.OffSet,SEEK_SET);
Holder=(UC *) calloc(Obj2.Hlen/2+1, sizeof(UC));
for(b=Obj2.Vlen;b>=0;b--)
fread(Holder, sizeof(UC), Obj2.Hlen/2, fp);
c=0;
in=0;
for(a=0;a<=Obj2.Hlen;a+=2)
c = (Holder[in] | 0x00) >>4;
putpixel(a+x,b+y,c);
c = (Holder[in] | 0xF0) & 0x0F;
putpixel(a+1+x,b+y,c);
in++;
free (Holder);
fclose(fp);
return 1;
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-< **** >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// Two bmp demo.bmp & demo1.bmp are provided.
// open these bmp in windows paint & change.(do not change size of bmp)
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-< Main >+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
void main()
int color,D=3,E=0;
//registerfarbgidriver(EGAVGA_driver_far);
initgraph(&D,&E,"C:\\BC31\\BGI");
E=0;
if(!ShowBMP(0,0,"C:\\imagen.bmp")) E=1;
getch();
closegraph();
if(E) printf("\nError.");
else printf("Sucess !");
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
【讨论】:
“它必须与内联汇编一起使用,因为它是一项家庭作业”。哎呀。以上是关于使用内联 ASM c++ 显示 640x480 BMP 图像的主要内容,如果未能解决你的问题,请参考以下文章