16位汇编下的屏幕截取程序

来源:互联网 发布:淘宝店铺招牌怎么上传 编辑:程序博客网 时间:2024/05/21 06:00

最近的汇编语言课程设计中,我分配到的题目是《屏幕截取程序》,要求是用16位汇编编写出一个dos界面下的屏幕截取程序,并且把截取到的屏幕保存成文件。

在对资料的搜索中,我发现网络上并没有类似的相关的博客或者教程之类的东西(只找到了一个win32位的汇编),所以可以说是在两眼一抹黑的情况下最终完成了程序的基本要求。为了记录一下自己的学习过程,也是为了以后遇到这个问题的人有一定的资料或者源代码可以参考,我决定写下我在csdn的第一篇博客。

这篇博客我会分为3个部分,第一个部分是我查找资料以及询问老师的一些过程,包括一些比较有用的博客地址。第二个部分是以我的实验报告为主的程序实现原理等,第三个部分是源代码的附件。

查找资料:

刚开始遇到这个问题的时候,跟大多数人一样,我选择的是进行网上的搜索,但是显然,这个16位汇编下的屏幕截取首先一没有其实用性,二来也算一个比较少见的实验课题。所以,就算经过了很长时间的寻找搜索,也没有找到类似的教程,只找到一个win32汇编下的屏幕截取程序,算是提供给了我的基本思路,但是由于win32和16位汇编的差异,我在注释较少的情况下基本无法看懂。下面这是win32屏幕截取程序的博客地址:http://blog.csdn.net/ppluer/article/details/51383097。这是第二篇,其余几篇麻烦自寻。

我尝试将这个程序转换成16位汇编,由于各种原因,最后并没有实现。但是也大致明白了这个程序所需的基本步骤,也就是抓取像素,保存在bmp文件中。

后来我去询问了我的汇编老师和在百度汇编语言吧里的大神相助,最终得到了编写这整个程序的基本思路,我会在第二个部分中具体阐述这个思路。

接下来就是查资料,无论是图书馆也好,还是网络也好,在查资料的过程中我受益匪浅,下面我会列出一些在编写这个程序中比较有用的链接和书籍:

书籍首先是我的教材,ibm-pc的汇编语言,其中的显示方式部分和读写像素部分十分重要。

链接有:http://www.cnblogs.com/xu_bright/archive/2008/11/05/1327519.html   bmp文件的格式

http://blog.csdn.net/ppluer/article/details/51383097  win32汇编的屏幕截取

实验步骤和报告:

这里的主要是我的实验报告的内容,不过也大致上描述清楚了这个实验的原理,具体内容如下:

问题描述

题目三十四 屏幕截取程序

设计一个汇编程序,可以截取屏幕并保存成图片文件。

 

问题分析

本题目要求设计者设计一个16位汇编语言程序,使其能在windows环境下的dos box里运行(即适用在16位汇编语言系统)。由于是16位汇编语言所编写的程序,该程序截取的屏幕实际上是dos box的屏幕。

保存成的图片文件,我在本次课程设计中选择的是bmp格式的文件,即位图文件。关于bmp文件结构的说明我会在第二部分详细讲解。

除题目要求之外,我额外完成了一个可以读取bmp文件并且在dos的屏幕上显示出来的程序,也会在之后的报告内容中加以描述和解释。

问题描述

本次课程设计的内容是,在16位的dos汇编的情况下,编写一个可以截取dos屏幕并将其在硬盘中保存下来,保存的格式是bmp位图文件格式,使其能直接用图片查看器进行打开。

问题具体化

1.如何进行屏幕的读取并将其保存在数据段中?

2.如何进行文件的读写?

3.如何进行bmp格式的保存?它与其他文件有何不同?

问题的要求和限制条件

1.用16位汇编语言进行编写。

2.环境使用masm for windows(也可使用其他)。

3.最终能得到可以直接打开查看的图片文件。

系统设计

完成此次课程设计需要解决的问题

1.进行像素点的读取,并且在读取整个屏幕的像素点后将其保存在数据段中,以便存取文件时使用。

2.运用中断调用建立程序,运用中断调用进行写文件的操作,把保存在数据段中的像素点写入要保存的文件中。

3.bmp文件结构的编写,每种不同后缀的文件有不同的结构,若是文件结构不正确,就不能最终直接打开。

同时需要注意的一些小问题

1.bios调用显示模式。

2.在dos界面上显示一些彩色图形(为了截图更明显一些)。

Bmp文件结构的解释说明

在本次编写bmp的文件结构过程中,我使用了汇编语言中的结构体。

bmp文件大体上分成四个部分。

第一部分为位图文件头BITMAPFILEHEADER,是一个结构。结构如下:

bmFile_header struc

 bfType dw ?;

 bfSize dd ?;

 bfReserved1 dw ?;

  bfReserved2dw ?;

 bfOffBits dd ?;

bmfile_header ends

bfType

指定文件类型,必须是0x424D,即字符串"BM",也就是说所有.bmp文件的头两个字节都是"BM"。

bfSize

指定文件大小,包括这14个字节。

bfReserved1,bfReserved2

为保留字,不用考虑

bfOffBits

为从文件头到实际的位图数据的偏移字节数,即bmp前三个部分的长度之和。

第二部分为位图信息头BITMAPINFOHEADER,也是一个结构,其定义如下:

 

 bminfo_header struc

 bisize dd ?

 biwidth dd ?

 biheight dd ?

 biplanes dw ?

 biBitcount dw ?

 bicompression dd ?

 bisizeimage dd ?

 bixpelpermeter dd ?

 biypelpermeter dd ?

 biclrUsed dd ?

 biClrimportant dd ?

 bminfo_header ends

biSize

指定这个结构的长度,为40。

biWidth

指定图象的宽度,单位是象素。

biHeight

指定图象的高度,单位是象素。

biPlanes

必须是1,不用考虑。

biBitCount

指定表示颜色时要用到的位数,常用的值为1(黑白二色图),4(16色图),8(256色),24(真彩色图)。

biCompression

不压缩为0。

biSizeImage

指定实际的位图数据占用的字节数。不压缩为0。

biXPelsPerMeter

指定目标设备的水平分辨率。

biYPelsPerMeter

指定目标设备的垂直分辨率。

biClrUsed

指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次方。

biClrImportant

指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。

第三部分为调色板,仅有使用16色图或者256色图需要使用调色板,若是真彩色图不需要使用调色板。

使用调色板的目的在于减小需要得形容某个像素颜色的字节位数。(在我显示16位色图的程序中使用到了调色板)。

第四部分就是实际的像素部分,由各个像素的颜色组成。

注意,对于2色位图,用1位就可以表示该像素的颜色(一般0表示黑,1表示白),所以一个字节可以表示8个像素。

对于16色位图,用4位可以表示一个像素的颜色,所以一个字节可以表示2个像素。

对于256色位图,一个字节刚好可以表示1个像素。

对于真彩色图,三个字节才能表示1个像素。

 

Bmp文件的结构部分描述到这里就结束了。

 

Bios调用显示模式的说明

显示模式分为两类,文本模式和图形模式,文本方式用于字符文本处理,而图形方式就是对所谓像素进行的处理。

Bios调用显示模式的功能号为00,调用参数为AL中的数据,中断是int10h。

常用的bios模式为03h,12h和13h。

03h:80*25  文本模式  16色或8色

12h:640*480 图形模式 16色

13h:320*200 图形模式 256色

 

模式如下:

  movah,00h

  mov al,13h

  int 10h

 

显示彩色字符的说明

使用bios的int 10h的功能号为09的中断调用。

此时,al中存储的是字符,bl中存储的是属性,而cx是字符显示的重复次数。

 

模式如下:

mov ah,09h

  mov al,'*'

  mov bh,0

  mov bl,0DAH

  mov cx,30

  int 10h

 

读写像素的说明

读写像素同样使用的是bios的int 10h中断。

读像素的功能号为0dh,而写像素的功能号为0ch。

本次课程设计中我们使用的是读像素,此时dx和cx分别存储的是像素的行和列,而读出来的像素的颜色存储在al当中。

 

模式如下:

Mov cx,0

Mov dx,0

Mov ah,0dh

Int 10h

就读出了0行0列的像素颜色存储在了al当中。

 

文件操作相关的说明

本次课程设计使用的文件操作运用了dos中断,即int 21h。

文件操作中涉及到了一个叫做文件句柄的东西,我们可以简单的把它理解为文件的代号。

创建文件   功能号3C   DX中存储文件的路径的首地址,CX是文件的属性,我们使用0即可。成功后将AX存入文件句柄handle中。

打开文件  功能号3D   DX中存储文件的路径的首地址,AL中存储访问文件的方式,(0读1写2读/写)。成功后把AX存入文件句柄handle中。

关闭文件  功能号3E   将handle存入BX中,调用即可。

写文件    功能号40   DX中存缓冲区的首地址,BX中存文件句柄,CX为写入的字节数。返回后AX中是成功写入的字节数。

读文件    功能号3F   DX中存缓冲区的首地址,BX中存文件句柄,CX为读取的字节数。返回后AX中是实际读取的字节数。


一些实验中的问题及解决:

实验中遇到的问题:

1.数据段只能限制在64kb内,无法将全屏截取下来。

2.bmp文件头难以编写。

3.起初实现了截取功能时,并不能得到完整的图像,截取的是一些色块,无法使用。

4.写入文件头,实现文件结构后仍然无法打开文件,提示文件损坏。

解决方案:

1.为了把文件限制在64kb以内,本来应该截取的320*200的图像,我缩减到了200*100的大小,即只能截取dos屏幕的一部分,不是全部。

2.为了实现bmp文件头的编写,自学了bmp的文件结构和汇编语言的结构体的编写和使用,为了简化编写过程使用了24位色图真彩色,无需编写调色板。

3.问题在于先对列进行了截取,后来进行逐行的截取,问题得到了解决。但是仍然会有截取的屏幕在最下方而不是上方,后来发现文件写入的顺序和屏幕的顺序相反,应该调换一下顺序才能在文件中显示正确的顺序。

4.原因是偶然间尝试用记事本打开我所生成的bmp文件,发现前两个字符并不是我预料中的BM而是MB(与我在设计时的顺序相反)。于是在代码中将’BM’改成‘MB’,程序得以顺利打开。


一股浓浓的报告风希望大家可以谅解,也只是希望能给以后遇到这个问题的同学提供一点思路。

这个程序还有许多可以完善的地方,比如常驻内存,或者说快捷键,或者说提示音等,但是由于本身就不具有什么实用性,所以只能说这是一个指引方向的文章吧。


源代码


到下列网址下载,由于源代码未编写注释,所以请结合上述说明使用。

http://download.csdn.net/detail/bwdashui/9907811?web=web

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 



 



               

           

原创粉丝点击