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
- 16位汇编下的屏幕截取程序
- windows32位汇编编写的屏幕锁定程序
- win7 64位下的16位汇编环境
- Java 屏幕截取程序
- android下截取当前屏幕程序中遇到的错误总结
- 【16位汇编】 模拟谈钢琴程序
- Windows下的64位汇编(1)
- Linux 下的64位汇编
- 截取屏幕的类
- Mac OS X下64位汇编与Linux下64位汇编的一些不同
- win32汇编代码的屏幕截屏程序
- 汇编屏幕显示3位数字子程序
- android截取view的视图 截取屏幕
- [编译环境][gcc]16位程序中汇编代码与C语言代码的混合编译
- WIN32汇编下的窗口程序
- Linux下C程序的反汇编
- 16位汇编与WIN32汇编的主要区别
- 截取屏幕的实现方法
- TCP三次握手与四次握手
- Let's Chat
- 机器学习笔记(三) 随便实现的logistic回归
- LeetCode--Merge Two Sorted Lists
- linux文件的访问控制
- 16位汇编下的屏幕截取程序
- 锅打灰太狼游戏
- POJ
- 计算几何--POJ--3304--Segments
- 20170723 做的事 ecdsa的签名验证时间短于bls signature
- lowbit
- 链表面试题之判断链表是否带环?若带环求环的长度?若带环求环的入口点?
- Ubuntu防火墙安装和配置
- pat-a1072. Gas Station (30)