从实模式到保护模式第13到16章笔记汇编.doc

上传人:ni****g 文档编号:549739807 上传时间:2023-10-18 格式:DOC 页数:7 大小:160.50KB
返回 下载 相关 举报
从实模式到保护模式第13到16章笔记汇编.doc_第1页
第1页 / 共7页
从实模式到保护模式第13到16章笔记汇编.doc_第2页
第2页 / 共7页
从实模式到保护模式第13到16章笔记汇编.doc_第3页
第3页 / 共7页
从实模式到保护模式第13到16章笔记汇编.doc_第4页
第4页 / 共7页
从实模式到保护模式第13到16章笔记汇编.doc_第5页
第5页 / 共7页
点击查看更多>>
资源描述

《从实模式到保护模式第13到16章笔记汇编.doc》由会员分享,可在线阅读,更多相关《从实模式到保护模式第13到16章笔记汇编.doc(7页珍藏版)》请在金锄头文库上搜索。

1、从实模式到保护模式第13到16章笔录汇编8.2用户程序的构造8.2.1分段、段的汇编地址和段内汇编地址办理器的工作模式是将内存分成逻辑上的段,指令的获取和数据的接见一律按“段地址:偏移地址”的方式进行。NASM编译器使用汇编指令“SECTION”也许“SEGMENT”来定义段。它的一般格式是SECTION段名称SEGMENT段名称align子句data1的汇编地址是0,段data2的汇编地址是理论上,若是不考虑段的对齐方式,那么段1,段data3的汇编地址是2。段的汇编地址其实就是段内第一个元素(数据、指令)的汇编地址。在段data1中声明和初始化的0x55位于汇编地址0x00000000处。

2、编译器将0x00000010作为段data2的汇编地址,并在两个段之间填充15字节的0x00段data3的汇编地址就是0x00000020(十进制的32)。段data3只有1字节8.2.2用户程序头部用户程序实质上定义了7个段,分别是第7行定义的段header、第27行定义的段code_1、第163行定义的段code_2、第173行定义的段data_1、第194行定义的段data_2、第201行定义的段stack和第208行定义的段trail。第7行:SECTIONheadervstart=0用户程序头部最少要包括以下信息。用户程序的尺寸,即以字节为单位的大小。应用程序的入口点,包括段地址和偏

3、移地址。第11、12行,依次声明并初始化了入口点的偏移地址和段地址。代码段code_1是在代码清单8-2的第27行定义的:SECTIONcode_1align=16vstart=0段重定位表。8.3加载程序(器)的工作流程8.3.1初始化和决定加载地址第6行,加载器程序的一开始声了然一个常数(const):app_lba_startequ100常数是用伪指令equ声明的,它的意思是“等于”。本语句的意思是,用标号app_lba_start来代表数值100,app_lba_startequ500用equ声明的数值不占用任何汇编地址,也不在运行时占用任何内存地址。它可是代表一个数值,就这么简单。/

4、加载用户程序需要确定一个内存物理地址,并初始化为0x10000的。和前面同样,是用这是在代码清单8-1第151行用伪指令32位的单元来容纳一个20位的地址:dd声的,phy_basedd0x100008.3.2准备加载用户程序第9行:SECTIONmbralign=16vstart=0x7c00第1214行,用于初始化货仓段存放器SS和货仓指针SP。此后,货仓的段地址是0x0000,段的长度是64KB,货仓指针将在段内0xFFFF和0x0000之间变化。第16、17行,用于获取一个地址,用户程序将要从这个地址处开始加载。这两条指令中都使用了段超越前缀“cs:”。这是赞同的,意味着在接见内存单元

5、时,使用CS的内容作为段基址。之所以没有使用DS和ES,是由于它们还有安排。第1821行,用于将该物理地址变成16位的段地址,并传达到DS和ES存放器。8.3.3外面设备及其接口外面设备分成两种,一种是输入设备;另一种是输出设备输入设备和输出设备统称输入输出(Input/Output,I/O)设备。不可以能将全部的I/O接口直接和办理器相连,设备那么多,还有些设备现在没有发明出来,将来必然会有。你怎么办?总线技术。每个设备的I/O接口都抢着和办理器说话,不发生矛盾都难。你怎么办?使用输入输出控制设备集中器(I/OControllerHub,ICH)芯片8.3.4I/O端口和端口接见外面设备和办

6、理器之间的通信是经过相应的I/O接口进行的。办理器是经过端口(Port)来和外面设备打交道的。端口就是存放器,近似于办理器内部的存放器。不同样之处可是在于,这些叫做端口的存放器位于I/O接口电路中。端口是办理器和外面设备经过I/O接口交流的窗口,每一个I/O接口都可能拥有好几个端口,分别用于不同样的目的。比方,连接硬盘的PATA/SATA接口就有几个端口,分别是命令端口、状态端口、参数端口。8.3.5经过硬盘控制器端口读扇区数据从硬盘读写数据,最经典的方式是向硬盘控制器分别发送磁头号、柱面号和扇区号,这称为CHS模式。从硬盘上读逻辑扇区过程:第1步,设置要读取的扇区数量。第2步,设置初步LBA

7、扇区号。第3步,向端口0x1f7写入0x20,央求硬盘读。第4步,等待读写操作达成。第5步,连续取出数据。8.3.6过程调用办理器支持一种叫过程调用的指令执行体系。过程又叫例程,也许子程序、子过程、子例程图8-13过程和过程调用表示图从代码清单8-1的第79行开始,向到达第131行结束,这就是我们所说的过程。代码清单8-1第79行是一个标号“read_hard_disk_0”,意思是读(第一个硬盘控制器的)主盘8-1的第8285行,用于将过程中用到的存放器压入货仓保留。代码清单第8789行,是向0x1f2端口写入要读取的扇区数。不问可知,每次读的扇区数是1个。第91101行,用于向硬盘接口写入

8、初步逻辑扇区号的低24位。低16位在存放器SI中,高12位在存放器DI中,需要不停地倒换到存放器AL中,以方便端口写入。第105行,程序执行到这里时,存放器AH的低4位是初步逻辑扇区号的2724位,高4位是全“0”;存放器AL中是0xe0。执行or指令后,将会在存放器AL中获取它们的组合值,高4位是0xe,低4位是逻辑扇区号的2724位。第118124行,用于屡次从硬盘接口那处获取512字节的数据,并传达到段存放器DS所指向的数据区中。每传达一个字,BX的值就增2,以指向下一个偏移地址。第126129行,用于把调用过程前各个存放器的内容从货仓中恢复。代码清单8-1第24、25行,用于指定用户程

9、序在硬盘上的初步逻辑扇区号。第26行用于指定存放数据的内存地址。第27行,开始调用过程read_hard_disk_0。今后,我们将把过程所在的标号做为过程的名字,即过程名。调用过程的指令是“call”。8086办理器支持四种调用方式:第一种是16位相对近调用。近调用的意思是被调用的目标过程位于当前代码段内,而非另一个不同样的代码段,所以只需要获取偏移地址即可。第二种是16位间接绝对近调用。这种调用也是近调用,只能调用当前代码段内的过程,指令中的操作数不是偏移量,而是被调用过程的真实偏移地址,故称为绝对地址。第三种是16位直接绝对远调用。这种调用属于段间调用,即调用另一个代码段内的过程,所以称

10、为远调用(FarCall)。返回指令ret和retf。ret和retf经常用做call和callfar的配对指令。ret是近返回指令,当它执行时,办理器只做一件事,那就是从货仓中弹出一个字到指令指针存放器IP中。retf是远返回指令(returnfar),它的工作稍微复杂一点点。当它执行时,办理器分别从堆栈中弹出两个字到指令指针存放器IP和代码段存放器CS中。call指令平时需要ret/retf和它配对,遥相响应,但ret/retf指令却其实不依赖于call指令,call指令在执行过程调用时不影响任何标志位,ret/retf指令对标志位也没有任何影响。8.3.7加载用户程序代码清单8-1第30

11、、31行,分别将该数值的高16位和低16位传达到存放器DX和AX。第32行,由于每扇区有512字节,故将512传达到BX存放器,并在第33行用它来做除法运算。代码清单8-1第34行,判断可否除尽。若是没有除尽,则转移到后边的代码,去读节余的扇区;若是除尽了,则总扇区数减一。第38行时,存放器AX中的内容必然为零。所以,第38行是算术比较指令cmp,第39行是条件转移指令,当存放器AX中的内容为零时,就意味着用户程序已经全部读取,不再连续读了,毕竟用户程序只占用一个扇区,而刚刚也已经读过了。代码清单8-1第42行,将当前数据段存放器DS的内容压栈保留。第44行,将用户程序节余的扇区数传达到存放器

12、CX,供后边的loop指令使用,由于我们准备采用循环的方法来读完用户程序。第4648行,将当前数据段存放器DS的内容在本来的基础上增加0x20,以构造出下一个逻辑段,为从硬盘上读取下一个512字节的数据做准备。第50行,将存放器BX清零。BX被用做数据传输时的段内偏移,而且每次传输都是在一新的段内进行,故偏移地址在每次传输前都应当是零。第51行,每次读硬盘前,将存放器SI的内容加一,以指向下一个逻辑扇区。第5253行,调用读硬盘的过程read_hard_disk_0,并开始下一轮循环,直到全部的扇区都读完(存放器CX的内容为0)。8.3.8用户程序重定位每个段在内存中的物理地址都是基于phy_

13、base代码清单8-1第55行,从货仓中恢复数据段存放器DS的内容,使其指向用户程序被加载的初步地址,也就是用户程序头部。第5862行用于重定位用户程序入口点的代码段。过程calc_segment_base(计算段基址)是在代码清单8-1的第134行定义的。第137行用于将其压栈保留。第139行,先将用户程序在内存中物理初步地址的低16位加到存放器AX中。第140行,再将该初步地址的高16位加到存放器DX中。代码清单8-1第141行,使用逻辑右移指令shr(SHiftlogicalRight)将存放器AX中的内容右移4位。ror(第142行),也就是循环右移(ROtateRight)。演示另一个不同样的指令代码清单8-1的第143行,用and指令将其清零。第144行,正式将存放器AX和DX的内容合并,这就是我们要的段地址。第146148行,恢复存放器DX的原始内容,并返回到调用程序那处。代码清单8-1的第62行,那条指令的功能是将方才计算出来的逻辑段地址回写到原处,仅覆盖低16位,高16位不用搭理。第6874行是循环体,每次循环开始后,BX总是指向需要重定位的段的汇编地址,而且都是双字,需要分别传达到存放器DX和AX。尔后调用过程calc_segment_base计算相应的逻辑段地址,并覆盖到本来的地址(低字),最后将基址

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 大杂烩/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号