纯x86汇编实现的多线程操作系统实践 - 第六章 AP1的用户进程

AP1用户进程的代码为task1.asm。

该用户进程将调用0x80系统中断在界面上显示一张BMP格式的图片。用户进程还使用了彩色转灰色技术,轮流显示该图片的彩色和灰色图。

代码解释如下:

调用0x39号系统中断,从300号扇区获得一个扇区的数据(512字节)到缓冲区buff中。一张32位色彩模式的BMP图片顺序的保存在硬盘上,300号扇区为图片数据的起始扇区。

BMP图片的格式如下:

其中,14字节的文件头部格式如下:

40字节的位图信息头格式如下:

更详细的解释可参考:https://www.cnblogs.com/kn-zheng/p/17001257.html

获取文件头中的文件长度,保存在pic_data_size中。再从位图信息头中获取图片的宽度,保存在pic_wide_size中。跳过54字节的BMP文件头(BMP文件头+位图信息头),直接就是BMP文件的位图数据(直接使用的是32位的色彩位图,BMP文件中没有调色板,文件头后直接跟32位的位图数据)。将buff缓冲区中的位图数据,以及位图数据长度作为参数,调用_draw_pic函数,显示图片的一部分。我们需要调用多次_draw_pic函数来逐步显示整张图片。

调用0x38号系统中断,用户进行将等待10ms后再继续执行。(由于连续读取硬盘扇区会导致VirtualBox重启,只能每次读取一个扇区的数据后,暂定一段时间)

当前读取的扇区号加一,然后读取下一个扇区的数据到buff缓冲区中。

pic_this_size记录本次调用_draw_pic显示图片时,传入数据的长度。pic_data_size记录图片还有多少位图数据未被显示。首先检测pic_data_size数据的长度,如果已经小于512字节,就将pic_this_size的值改为pic_data_size;否则每次用于显示的位图数据的长度都为512字节。

调用_draw_pic函数,显示图片。

剩余的位图数据长度减去本次用于显示的数据长度,如果图片所有位图数据都显示完毕,则跳转到_sleep处,等待1秒钟后,再一次从头开始显示图片;否则跳转到_disk_read处,继续读取下一个扇区,进行图片的显示。

执行到这里,说明图片的所有数据已经显示完毕,等待1秒钟。

复位各变量,如保留图片数据的起始扇区,图片左下角的X轴、Y轴等,其中,pic_color_fix标记用于告诉_draw_pic函数,显示彩色图片还是灰色图片。然后跳转到_again_and_again,开始重新显示图片。

下面介绍_draw_pic函数,该函数真正在界面上显示图片。

首先判断上一次调用_draw_pic函数时,是否还留下2字节的数据未显示。由于BMP文件的头部为54字节,一个扇区为512字节,一个RGB点需要4字节来保存色彩,这导致每次调用_draw_pic显示一个扇区的数据时,总会留下2字节的数据未显示。因此,tmp_data_size总等于2。

在这里,只要tmp_data_size不为0,本次显示的数据长度增加2,同时保留数据的缓冲头部往前移动2字节,再将tmp_data_size清零。这里为什么直接将保留数据的缓冲头部往前移动2字节?原因是每次剩下的未显示的2字节数据都被_draw_pic保留到tmp_data开头的2字节的缓冲区中,而tmp_data正好被放在buff这个缓冲区的前面2字节处,正好跟新读取的图片数据连在了一起…

如果剩余数据的长度小于等于2,就跳出_draw_pic函数。

这里在为调用0x80号中断,显示一个点做准备:x_coordinate为显示点的X轴,y_coordinate为显示点的Y轴,edx中保留本次要显示的32位色彩。再判断pic_color_fix的奇偶性,为奇数,就调用_color_to_gray函数,将本次要显示的点的颜色变为灰色。

调用0x80号系统中断,显示一个点。之后数据长度减4,数据指针加4,指向后一个点的32位颜色数据。

显示点的X坐标右移一位。判断本行是否已显示完毕。若是,下一个显示点的X坐标返回到预设值(就是图片左下角的X坐标),Y坐标减一,开始显示上一排的点。(由于大部分BMP文件都是倒向位图,如果按照从左往右从上往下的顺序进行点的显示,最终得到的是一张倒图。因此需要从下往上倒过来进行显示)

这里跳回_draw_pic_0处,继续从缓冲区获取下一个点的颜色数据,然后显示。

执行到这里,说明缓冲区中剩下的数据已经小于等于2。先判断数据长度是否为0,若是,说明图片的数据已经全部显示,退出_draw_pic函数;否则,将本次未显示的2字节数据保存到tmp_data缓冲区中,并置tmp_data_size为2,提醒还有2字节数据需要显示。

最后是_color_to_gray函数,该函数是将一个彩色点转变为灰色点,具体的公式是:Gray= 0.2989 * R + 0.5870 * G + 0.1140 * B。函数简单,这里就不再进行讲解。

task1.asm源代码地址:https://download.csdn.net/download/hanspruce_bird/87502149

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值