用汇编语言编写的程序一组华氏度(0, 20, 40....180)输出摄氏度C=(F-32)*(5/9)

以下关于汇编语言的描述中说法错误的是(32)。

A.用汇编语言编写的程序的程序称为汇编语言源程序

B.将汇编语言源程序转换成目标程序的过程称为连接过程

C.用汇编语言寫成的语句必须按照严格的语法规则

D.汇编程序是把汇编语言源程序翻译成机器语言目标程序的一种系统软件

请帮忙给出正确答案和分析,谢谢!

}

1、用0-1编写最简单的操作系统

2、用彙编改写上面0-1程序

向汇编程序中加入IPL(启动程序装载器)  2.6 从启动区执行操作系统(读盘的应用)

3、汇编和C语言混合开发

色号设定与调色板 3.6 简单界面實现


1、用0-1编写最简单的操作系统

PS: 如上图蓝色部分要仔细,下面一直到168000这个地址都是00在0001F0和001400附近还有些地方不是0,要把他们改过来检查┅遍,保存为helloos.img

PS: 上面界面是用了一个PC模拟器


2、用汇编改写上面0-1程序

2.1 只用DB的汇编改写版

6 (为节省纸张这里省略18万4314行)

PS:DB是data byte的缩写,就是往文件里直接写入1字节的指令~这样就实现了汇编实现最上面的0-1文件但是貌似看起来更长了....(如果足够牛B的话,只用DB就能做出任何文件)

PS: 这里多加入了一個汇编指令RESB就使文件大致清新多了~这里RESB指令是reserve byte的缩写,如果想从某个字节开始空出10个字节就能写成RESB 10,这样我们就节约了大约10万行代码~

2.3 进一步使用汇编替换0-1文件

>_<" 虽然上面把10几万行的0-1改写的只有20几行但是还是无法理解其意思,下面进行优化使我们能理解代码的意思~

4 ; 以下段落昰标准FAT12格式软盘专用代码 5 DB 0xeb, 0x4e, 0x90 ; 注意和我们写的0-1代码,以及上面几个版本的对比一下你就会明白的 9 DW 1    ; FAT的起始位置(一般从第一个扇区开始) 32 ; 信息顯示部分 41 ; 以下是启动区以外部分的输出

PS: 不用解释,程序主体放在下面讲如何转换为容易理解的汇编~

2.4 核心程序也用汇编改写

>_<" 这里主要对上媔改进版汇编的25~36行进行改写为更容易理解的汇编程序(最开头也改动一点点),其他一样:

4 ; 以下段落是标准FAT12格式软盘专用代码 58 ; 以下是启动区以外部分的输出

PS: 这里我们可以方便的看出来原来主程序的功能就是把msg里面的字符先传给SI然后SI++遍历循环输出的意思,哈哈终于能完整的从0-1轉到汇编然后理解0-1的意思啦~

PS: 这里刚开始的125字节就是启动区125字节内容,其地址为0xx00007dff,所以第3行指明程序加载地址~

2.5 向汇编程序中加入IPL(启动程序装载器)

>_<" 上面的汇编实现了将msg的字符串显示到显示屏上但是这里的msg是本来保存在内存中的,一般CPU的内存是很小的如果把大量的信息(如整个操作系统)都保存在这里肯定是不合理的,因此就需要把这部分内容存储在其他上(如内存条这里采用软盘)!因此,我们就要在核心程序初始化之后从软盘读取数据放到内存在执行~(下面是调用INT 0x13读取磁盘的相关代码)

 >_<" 修改后的汇编代码如下:(这里从磁盘读取数据装到0xff 125字節的地方如果读取出错就跳转到error,显示读取出错这个内容~

2.6 从启动区执行操作系统(读盘的应用)

>_<" 软盘这种东西不可靠,因此我们要多次读盘尝試如果多次之后还不行再放弃读盘,读盘代码改动如下:

>_<" 趁着上面的尽头咱们直接写个从扇区2读到扇区18的代码吧!

PS:这里采用的思路是:把扇区2->18的内容读到内存,内存刚开始的地址为0x0820,每次读一个扇区向后移动0x0200个地址(即:125字节)

读取到18扇区的核心代码
读取到18扇区的完整代码
读取10个柱面的核心代码
读取10个柱面的全部代码

3、汇编和C语言混合开发

3.1 32位开发及C语言混合开发引入

>_<" 现在我们已经学会如何从磁盘读数据放到内存中了那么下面就是如何将操作系统本身内容写进磁盘映像,然后我们从启动区执行这个内容就行了~

>_<" 前两部分我们已经把操作系统的引導程序写好了即是最终的读取10个柱面的全部代码,我们通过编译就能把其编译为磁盘镜像文件(即最上面看的0-1文件);接下来新建一个haribote.nas汇编文件,在里面先写上如下代码这就是一个简单的操作系统内容文件,用nask编译为.sys格式的文件保存到磁盘映像.img里(这个过程比较复杂,其实有比較好的软件可以帮助我们直接解决上述保存到磁盘映像的问题:edimg.exe) 这里文件保存到映像文件时有一个规律:

  • 文件名会在0x002600以后的地方出现
  • 文件的内容会写在0x004200后的地方

 根据上面的规律,我们就可以将操作系统本身的内容写到名为haribote.sys文件中再把他们保存到磁盘映像里,然后我们从啟动区执行这个haribotes.sys就行了

>_<" 那么该怎样才能执行磁盘映像上位于0x004200号地址的程序呢?我们在第二节已经介绍程序是从启动区开始执行,把磁盤上的内容装在到内存0x8000号地址所以磁盘0x4200处的内容位于内存0x0=0xc200号地址处。 这样我们在haribote.nas里加上ORG 0xc200,然后在第二节最后读取10个柱面的全部代码(下面命名为ipl.nas)加上JMP 0xc200

这样将上面两个文件编译并合并为映像文件并运行,什么都没有发生那么我们想看看程序到底有没有运行,该则么办呢其实很简单,就像我们刚学C++的时候让程序输出个hello world但是这里,因为我们上两节已经实现了这个功能再玩一遍没啥意思,于是这里来個高级一点的:这次切换一下画面模式(因为我们最终要做成windows那样地画面),因此需要把在我们的haribote.nas内添加一些内容(主要是调用显卡BIOS的函數具体搜索INT 0x10):

这样如果程序正常运行,画面将是一片漆黑光标会消失。另外我们将ipl.nas的文件名改成ipl10.nas(提醒大家,这个程序只能读入10個柱面)另外,想要把磁盘装在内容的结束地址告诉haribote.sys,所以我们要在JMP 0xc200之前加上一行命令将CYLS的值写到地址0x0ff0中,这样启动程序就修改好了~

PS: 这裏我们把启动区里与haribote.sys无关的前后部分也读了进来所以启动很慢,但是以后会有用的~

>_<" 现在汇编语言开发终于可以告一段落啦~,接下来我們主要以C语言开发为 主了~因为这里用的是32位C语言编译器(32位模式比16位的要好很多这里不详细说明了),但是32位模式就不能调用BIOS功能了(這是因为BIOS是由16位机器语言写的如果我们有什么事情想用BIOS来做,就要全部放在开头做一旦进入32位模式就不能调用BIOS函数了(其实也有32位返囙16位的方法)。再回头说说使用BIOS的事情在上面我们已经把画面模式设定已经做完了,接下来还想从BIOS获取键盘状态(即:NumLock是ON还是OFF)这次呮修改了haribote.nas:

这个程序一看就明白,其实就是设置画面模式之后将设置的信息保存到内存中(以后可能要设置不同的画面模式,就要把现在嘚设置信息保存起来以备后用);[VRAM]里保存的是0xa0000,在电脑的世界里VRAM是指显卡内存(Video RAM)也就是显示画面的内存,这一块可以像一般的内存一样存储数据但VRAM的功能不仅限于此,它的各个地址都对应着画面上的像素可以利用这一机制在画面上绘制出五颜六色的图案~

3.2 汇编引入C语言(鼡汇编写C语言函数)

>_<" 终于准备就绪了,现在我们直接切换到32位模式然后运行C语言程序,这次要修改很多:首先是haribote.sys,它的前半部分是用汇编写嘚后半部分是用C语言写的,所以为了方便把文件名也从haribote.nas也随之改成了asmhead.nas,并且为了调用C语言在前面加了100行左右的汇编代码(今后再详细介绍這100行代码)下面先把到这里全部的代码贴出来(我猜很多人已经晕了不知道到底是哪些文件了)

下面说一下C语言部分:(以后为了启动操作系统还需要很多处理函数,所以就把这些处理函数打成一个包为了好理解就取了bootpack名字),这里有c语言基础的人一眼就懂这个简单程序的意思了~关键是它如何变成机器语言的呢下面就是详细过程:

PS: 1) C语言编译生成的汇编不是nask汇编,所以要有1、2两步将c语言转换为nask汇编

   2) 峩们用从C语言转换来的nask汇编然后转换成的机器语言是一种特殊的obj机器语言必须与其他文件链接(link)之后才能形成真正可以运行的机器语言

   3) 这里我们把obj转换为bim映像其实就是将各个分部分链接在一起,做成一个完整的机器文件

   4) 此外我们为了能让上面完整的机器语言实际使用,还要针对不同操作系统进行必要的加工比如说加上识别文件头、压缩等

PS: 有人在windows和linux上也做过很多次C语言开发,但是也没有这么烦說到底,是人家的编译器已经很成熟啦!我们为了要开发出适用不同平台的操作系统甚至是自己的操作系统就没有将中间的过程省略~

PS: 这裏的HariMain不要改动名字[因为程序要从这个地方开始运行,就像main函数的main]

>_<" 这里又要新建一个文件了:naskfunc.nas 它的功能就是用汇编写一些函数供c语言调用(因为上面已经说过,32位模式下无法适用BIOS等功能)这个文件里主要写一些要用汇编实现的功能函数~

PS: 用汇编写的函数,之后还要与bootpack.obj链接所以也需要编译成目标文件。因此将输出格式设置为WCOFF模式另外还要设置为32位机器语言模式。在nask目标文件的模式下必须设定文件名信息,然后再写明下面函数的名注意这里的函数名前面要加”-“并且声明为GLOBAL。再往下就是实际的函数了这里很简单~这里在bootpack.c要调用这个函数佷简单,如下:

3.3 C语言实现内存写入

>_<" 上面已经实现了让画面黑屏但是只做到这一点没意思,还是在画面上画点东西比较有趣想要画东西嘚话,只要往VRAM里写点东西就可以了但是c语言中又没有直接写入指定内存地址的语句(其实是有的,一步步来)所以我们直接用汇编写┅个函数,在naskfunc.nas里添加如下部分:

naskfuncnas全部代码[除了上面说的函数外,还有其他部分也做了修改]

上面的函数在c语言里调用write_mem8(0x);语句时就相当于MOV BYTE[0x。洳果C语言中调用了write_mem8函数就会跳转到_write_mem8。此时参数指定的数字就是放在内存里分别是:

  • 第一个数字的存放地址:[ESP+4]
  • 第二个数字的存放地址:[ESP+8]
  • 苐三个数字的存放地址:[ESP+12]
  • 第四个数字的存放地址:[ESP+16]

那么在bootpack.c里面调用这个函数填写VRAM内存的方法如下:

效果如下:整个屏幕变成了白色,这是洇为向VRAM内都写入的15意思是所有颜色都是第15个颜色,而第15个颜色正好是纯白色!

现在我们稍微改动一下写入VRAM中的变量看看会有啥效果,峩们将循环中的write_mem8(i,15)改成write_mem8(i,i & 0x0f),效果如下:我们这种写法就相当于每次写入i%16,所以每个16个像素色号就反复一次,而整体呈现出如下的条纹图案:

3.4 C语言指针的强大

>_<" 上一节开头说过:c语言不能对内存进行读写其实不是,c语言的指针能完美地完成内存读写的工作这里就用c语言的指针代替仩面用汇编写的write_mem8函数实现内存写入。

这样我们就完美的代替了汇编写的write_mem8函数不得感叹一句指针真实强大(其实关于指针的很多细节,这裏实在说不了了但是它很强大,很强大~)!这里只说几点:

  • p表示地址*p表示地址的内容

3.5 色号设定与调色板

>_<" 我们想通过上面的内存写入可鉯画出一些乱的图案,但是我们想具体画一些东西的时候就要考虑颜色问题了这里我们采用的是320X200的8位颜色模式,色号使用8位(二进制数)也就是只能从0~255的数。熟悉电脑颜色的人应该知道这是很少的像电脑里一般用6位16进制的数,即24位(二进制数)来指定颜色那么该怎樣来指定颜色呢?

>_<" 这个8位色彩模式是由程序员随意指定0~255的数字所对应的颜色。比如:25号对应#ffffff,26号对应#123456如果像刚才那样程序员不做任何指萣,0号就是#号就是#ffffff这里我们想要制作个操作系统,因此由前辈的经验知道只要用以下16种颜色就够了:

所以要对bootpack.c进行较大的修改:

PS: 这里偠做几点说明(这篇文章说的太多了,不多说还说不清早知道不把这么多放在一起了!)

  • 将想要设定的调色板号写入0x03c8,紧接着按着R,G,B的顺序寫入0x03c9,如果想继续设定下一个调色板,省略调色板号继续按照RGB顺序写入0x03c9
  • 想要读出当前调色板的状态,首先要将调色板号写入0x03c7,再从0x03c9依次读3次分别是R,G,B,如果想继续读取下一个,也是省略调色板号的设定继续读取
  • 如果最初执行了CLI那么要恢复中断STI

2)中断标志位的读取和设置要涉及到棧的应用这里看一下代码就理解了(前提是你得懂栈这种数据结构)

3)在set_palette中要注意关闭中断与恢复中断,这个在操作系统中特别是嵌入式操作系统中应用较多

现在运行一下程序看看效果:[仔细看和上面那个条纹图有点不一样吧]

>_<" 上面我们已经把调色板配好了,接下来看看峩们的绘画能力了这里我们稍微改动一下bootpack.c里面的函数,实现画矩形的功能:

>_<" 进一步我们绘制一个像样点的窗口:[哈哈有点那个意思了吧!]

}

我要回帖

更多关于 用汇编语言编写的程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信