付费下载
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第六章程序的动态加载与执行主引导程序进入保护模式前建立的GDT内核加载进入内核执行用户程序结构用户程序加载用户程序段的重定位和描述符的创建重定位用户程序内的符号地址6.1主引导程序进入保护模式前建立的GDT主引导程序进入保护模式前建立的GDT主引导程序由ROM-BIOS加载到物理地址0x7C00处,所以从该处向高地址到0x7E00-1为512字节的初始化代码段(即主引导程序);从物理地址0x7C00处向低地址扩展是4KB的内核堆栈段,即0x7C00至0x6C00;所以可以将GDT安排在主引导程序之后,即0x7E00处,紧挨着初始化代码段,GDT大小是可变的,最大可达64KB,注意一定要留足空间(0x7E00~0x17E00-1);从0xB8000处扩展32KB,是文本模式的显示缓冲区。6.1主引导程序进入保护模式前建立的GDT主引导程序进入保护模式前建立的GDT表内偏移量描述符索引0x00空描述符0x000x080~4GB数据段(00000000~FFFFFFFF)0x080x10初始代码段(00007C00~00007DFF)0x100x18初始栈段(00006C00~00007C00)0x180x20文本模式显存(000B8000~000BFFFF)0x206.1主引导程序进入保护模式前建立的GDT0~4GB数据段(00000000~FFFFFFFF)0x00cf92000000ffff;G=1,粒度4KB;D/B=1,32位的偏移地址或操作数;L=0,AVL=0;P=1,段存在;DPL=00,描述符特权级=0;S=1,代码段或者数据段;TYPE=0010,读、写;基地址=0x00000000;段界限=0xFFFFF6.1主引导程序进入保护模式前建立的GDT初始代码段(00007C00~00007DFF)0x004098007c0001ff;G=0,粒度1B;D/B=1,32位的偏移地址或操作数;L=0,AVL=0;P=1,段存在;DPL=00,描述符特权级=0;S=1,代码段或者数据段;TYPE=1000,只执行;基地址=0x00007C00;段界限=0x001FF。6.1主引导程序进入保护模式前建立的GDT初始栈段(00006C00~00007C00)0x00cf96007c00fffe;G=1,粒度4KB;D/B=1,32位的偏移地址或操作数;L=0,AVL=0;P=1,段存在;DPL=00,描述符特权级=0;S=1,代码段或者数据段;TYPE=0110,读、写、向下扩展;基地址=0x00007C00;段界限=0xFFFFE。6.1主引导程序进入保护模式前建立的GDT文本模式显存段(000B8000~000BFFFF)0x0040920b80007fff;G=0,粒度1B;D/B=1,32位的偏移地址或操作数;L=0,AVL=0;P=1,段存在;DPL=00,描述符特权级=0;S=1,代码段或者数据段;TYPE=0010,读、写;基地址=0x000B8000;段界限=0x07FFF。6.2内核加载内核程序结构内核程序包括内核头部、公共例程段、内核数据段、内核代码段。内核头部组成偏移地址内核信息0x00内核总长度0x04公共例程段起始汇编地址0x08公共数据段起始汇编地址0x0c内核代码段起始汇编地址0x10内核入口点(段:偏移)6.2内核加载读取内核程序的第一个扇区根据内核程序的第一个扇区里的程序头部数据,获取内核程序的总扇区数,循环读取其他扇区例程read_hard_disk_0:EAX存放28位的逻辑扇区号,EBX加载的偏移地址,执行完后,EBX加512。创建与内核有关的段描述符过程make_gdt_descriptor:输入:EAX为段的基地址;EBX为段界限;ECX为段属性,各属性位的位置和描述符高32位一致,
和属性无关位清0。输出:EDX:EAX为完整的段描述符。6.2内核加载make_gdt_descriptor:;构造描述符movedx,eaxshleax,16orax,bx;描述符前32位(EAX)构造完毕
andedx,0xffff0000;清除基地址中无关的位
roledx,8bswapedx;装配基址的31~24和23~16(80486+)xorbx,bxoredx,ebx;装配段界限的高4位
oredx,ecx;装配属性
ret。6.2内核加载在GDT中加入内核程序的各个段描述符。表内偏移量描述符索引0x00空描述符0x000x080~4GB数据段(00000000~FFFFFFFF)0x080x10初始代码段(00007C00~00007DFF)0x100x18初始栈段(00006C00~00007C00)0x180x20文本模式显存(000B8000~000BFFFF)0x200x28公共例程段(起始地址为0x00040000)0x280x30核心数据段(位于系统公共例程段之后)0x300x38核心代码段(位于核心数据段之后)0x386.2内核加载在GDT中加入内核程序的各个段描述符(edi保存的是内核程序加载的物理内存首地址)movesi,[0x7c00+pgdt+0x02];不可以在代码段内寻址pgdt,
但可以通过4GB的段来访问;建立公用例程段描述符
moveax,[edi+0x04];公用例程代码段起始汇编地址
movebx,[edi+0x08];核心数据段汇编地址
subebx,eaxdecebx;公用例程段界限
addeax,edi;公用例程段基地址
movecx,0x00409800;字节粒度的代码段描述符
callmake_gdt_descriptormov[esi+0x28],eaxmov[esi+0x2c],edx6.2内核加载在GDT中加入内核程序的各个段描述符(edi保存的是内核程序加载的物理内存首地址)
;建立核心数据段描述符
moveax,[edi+0x08];核心数据段起始汇编地址
movebx,[edi+0x0c];核心代码段汇编地址
subebx,eaxdecebx;核心数据段界限
addeax,edi;核心数据段基地址
movecx,0x00409200;字节粒度的数据段描述符
callmake_gdt_descriptormov[esi+0x30],eaxmov[esi+0x34],edx6.2内核加载在GDT中加入内核程序的各个段描述符(edi保存的是内核程序加载的物理内存首地址)
;建立核心代码段描述符
moveax,[edi+0x0c];核心代码段起始汇编地址
movebx,[edi+0x00];程序总长度
subebx,eaxdecebx;核心代码段界限
addeax,edi;核心代码段基地址
movecx,0x00409800;字节粒度的代码段描述符
callmake_gdt_descriptormov[esi+0x38],eaxmov[esi+0x3c],edxmovword[0x7c00+pgdt],63;描述符表的界限
lgdt[0x7c00+pgdt]6.3进入内核执行主引导程序通过4GB的数据段访问内核的头部,用间接远转移指令从给定的入口进入内核执行。在内核头部偏移0x10处,是6字节的内核入口点。前面是32位的段内偏移地址,后面是16位的段选择子,指向内核代码段。获取CPU特征信息:cupid指令:用于返回处理器的表示和特性信息。EAX用于指定要返回什么样的信息,也就是功能,有时候还需要用到ECX寄存器。cupid指令执行后,处理器将返回的信息放在EAX、EBX、ECX或者EDX中。EFLAGS寄存器的ID标志位如果为0,则该处理器不支持cpuid指令,反之,则支持cpuid指令。为了探测处理器能够支持的最大功能号,应该先用0号功能来执行cpuid指令,EAX寄存器返回处理器能够支持的最大功能号,同时,还在EBX、EDX、ECX中返回处理器供应商的信息。要返回处理器的品牌信息,需要使用0x80000002~0x80000004功能。6.4用户程序结构用户程序结构用户程序包括程序头部、用户程序数据段、用户程序代码段。用户头部组成偏移地址内核信息0x00用户程序总长度,以字节为单位0x04用户程序头部长度,以字节为单位0x08为栈保留的0x0c要求分配的栈大小,以4KB为单位0x10用户程序入口点的32位偏移地址6.4用户程序结构用户头部组成偏移地址内核信息0x14用户程序代码段的起始汇编地址,定位完成后由内核程序,改为该段的选择子0x18用户程序代码段的长度,以字节为单位0x1c用户程序数据段的起始汇编地址,定位完成后由内核程序,改为该段的选择子0x20用户程序数据段的长度,以字节为单位0x24符号-地址索引表的表项数目0x28符号地址索引表的起始位置,每一项256字节。6.4用户程序结构用户头部组成符号-地址索引表(Symbol-AddressLookupTable,SALT):
内核要求,用户程序必须在头部偏移量为0x28的地方构造一个表,并在表格中列出所要用到的符号名。每个符号名的长度是256字节,不足的部分用0x00填写,这意味着每个符号名的长度最多可以是256个字符。在用户程序加载后,内核会分析这个表,并将每一个符号名替换成相应的内存地址,这就是过程的重定位。为了方便起见,我们将这个表称为符号-地址索引表(Symbol-AddressLookupTable,SALT)。偏移量为0x24处的双字,是SALT的表项数目。
当然,调用操作系统提供的例程,可以使用软中断的方式提供。6.5用户程序加载用户程序加载例程load_relocate_program输入:ESI保存用户程序的起始逻辑扇区号;输出:AX寄存器包含了指向用户头部段的段选择子。先读出用户程序的第一个扇区,缓存到内核程序的数据段中的一个缓冲区core_buf;分析缓冲区core_buf中存放的用户程序的头部,得到用户程序的总的大小,计算出用户程序占用的总的扇区数;内核数据段中ram_alloc处的双字,保存了可以分配内存的首地址,初始为0x10000;根据用户程序的大小,调用例程allocate_memory为用户程序的加载进行动态内存分配;循环调用read_hard_disk_0例程,加载整个用户程序。6.5用户程序加载动态内存分配例程allocate_memory输入:ECX保存希望分配的字节数;输出:ECX包含了所分配内存的起始物理地址。allocate_memory:;分配内存
;输入:ECX=希望分配的字节数
;输出:ECX=起始线性地址
pushdspusheaxpushebxmoveax,core_data_seg_selmovds,eaxmoveax,[ram_alloc]addeax,ecx;下一次分配时的起始地址6.5用户程序加载动态内存分配例程allocate_memory
;这里应当有检测可用内存数量的指令
movecx,[ram_alloc];返回分配的起始地址
movebx,eaxandebx,0xfffffffcaddebx,4;强制对齐
testeax,0x00000003;下次分配的起始地址最好是4字节对齐
cmovnzeax,ebx;如果没有对齐,则强制对齐
mov[ram_alloc],eax;下次从该地址分配内存
;cmovcc指令可以避免控制转移
popebxpopeaxpopdsretf6.5用户程序加载动态内存分配例程allocate_memorytest指令:测试相应的位是否为0,与and类似,但是不改变操作数的值,只改变EFLAGS的相应标志位。条件传送指令cmovcc:该系列指令是从P6处理器族开始引入的,因此并非所有的处理器都支持它,可以先使用1号功能执行cpuid指令,检测CPU是否支持该系列指令。cpuid指令执行后,检查EDX寄存器的第16位(bit15),如果是1,表示该处理器支持该系列指令。cmovzax,cx ;为0则传送cmovnzeax,[0x2000]; 不为0则传送cmoveebx,ecx; 相等则传送cmovngcx,[0x1000];不大于则传送cmovledx,ecx;小于则传送6.6用户程序段的重定位和描述符的创建
建立程序头部段描述符
moveax,edi;程序头部起始线性地址
movebx,[edi+0x04];段长度
decebx;段界限
movecx,0x00409200;字节粒度的数据段描述符
callsys_routine_seg_sel:make_seg_descriptorcallsys_routine_seg_sel:set_up_gdt_descriptormov[edi+0x04],cx6.6用户程序段的重定位和描述符的创建建立程序代码段描述符
moveax,ediaddeax,[edi+0x14];代码起始线性地址
movebx,[edi+0x18];段长度
decebx;段界限
movecx,0x00409800;字节粒度的代码段描述符
callsys_routine_seg_sel:make_seg_descriptorcallsys_routine_seg_sel:set_up_gdt_descriptormov[edi+0x14],cx6.6用户程序段的重定位和描述符的创建建立程序数据段描述符
moveax,ediaddeax,[edi+0x1c];数据段起始线性地址
movebx,[edi+0x20];段长度
decebx;段界限
movecx,0x00409200;字节粒度的数据段描述符
callsys_routine_seg_sel:make_seg_descriptorcallsys_routine_seg_sel:set_up_gdt_descriptormov[edi+0x1c],cx6.6用户程序段的重定位和描述符的创建建立程序堆栈段描述符
movecx,[edi+0x0c];4KB的倍率
movebx,0x000fffffsubebx,ecx;得到段界限
moveax,4096muldword[edi+0x0c]movecx,eax;准备为堆栈分配内存
callsys_routine_seg_sel:allocate_memoryaddeax,ecx;得到堆栈的高端物理地址
movecx,0x00c09600;4KB粒度的堆栈段描述符
callsys_routine_seg_sel:make_seg_descriptorcallsys_routine_seg_sel:set_up_gdt_descriptormov[edi+0x08],cx6.6用户程序段的重定位和描述符的创建例程set_up_gdt_descriptor:;在GDT内安装一个新的描述符
;输入:EDX:EAX=描述符
;输出:CX=描述符的选择子
pusheaxpushebxpushedxpushdspushesmovebx,core_data_seg_sel;切换到核心数据段
movds,ebxsgdt[pgdt];以便开始处理GDTmovebx,mem_0_4_gb_seg_selmoves,ebx6.6用户程序段的重定位和描述符的创建movzxebx,word[pgdt];GDT界限
incbx;GDT总字节数,也是下一个描述符偏移
addebx,[pgdt+2];下一个描述符的线性地址
mov[es:ebx],eaxmov[es:ebx+4],edxaddword[pgdt],8;增加一个描述符的大小
lgdt[pgdt];对GDT的更改生效6.6用户程序段的重定位和描述符的创建movax,[pgdt];得到GDT界限值
xordx,dxmovbx,8divbx;除以8,去掉余数
movcx,axshlcx,3;将索引号移到正确位置
popespopdspopedxpopebxpopeaxretf6.6用户程序段的重定位和描述符的创建sgdt指令:要在GDT内安装段描述符,必须知道它的物理地址和大小。而需要知道这些,可以使用指令sgdt(StoreGlobalDescriptorTableRegister),它用于将GDTR寄存器的基地址和边界信息保存到指定的内存位置。sgdt的格式为:sgdtm其中m是一个6字节内存区域的首地址。该指令不影响任何标志位。
6.6用户程序段的重定位和描述符的创建movzx指令:其作用是带0扩展的传送(MovewithZero-Extend),指令格式为:movzxr16,r/m8movzxr32,r/m8movzxr32,r/m16movzx指令的目的操作数只能是16位或者32位的通用寄存器,源作数只能是8位或者16位的通用寄存器、或内存单元的地址。如:movzxcx,almovzxeax,byte[0x2000]movzxecx,bx6.7重定位用户程序内的符号地址为了使用内核提供的例程,用户程序需要建立一个符号-地址对照表(SALT)。这样,当用户程序加载后,内核应当根据这些符号名来回填它们对应的入口地址,这称为符号地址的重定位。显然,重定位的过程就是字符串匹配和比较的过程。为了对用户程序内的符号名进行匹配,内核也必须建立一张符号-地址对照表(SALT)。用户程序内的SALT表,每个表项是256个字节,用于容纳符号名,不足256字节的,用0填充。内核中的SALT表,每个条目则包含两个部分,第一部分也是256字节的符号名;第二部分有6个字节,用于容纳对应例程的4字节偏移地址,和2字节的段选择子,这6个字节其实就是例程的入口地址。我们将用户程序的SALT简称为U-SALT,将内核的SALT简称为C-SALT。6.7重定位用户程序内的符号地址在用户程序加载时,内核的任务是比对U-SALT和C-SALT,并将用户程序SALT表中的符号名替换成相应的入口地址。cmps指令:字符串的比较,有三种基本形式:cmpsb:字节比较;cmpsw:字比较;cmpsd:双字比较在16位模式中,源字符串的首地址由DS:SI指定,目的字符串的首地址由ES:DI指定;在32位模式下,源字符串的首地址由DS:ESI指定,目的字符串的首地址由ES:EDI指定。如果EFLAGS中的DF=0,表明是正向比较,即按地址递增方向比较,这些指令执行后,SI(ESI)和DI(EDI)的内容加1、加2和加4;否则,DF=1,表明是反向比较,即按地址递减方向比较,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 桥梁结构试验试题及答案
- 广东省清远市英德市2024-2025学年八年级上学期期末地理试题(含答案)
- 《GAT 1329-2016法庭科学吸毒人员尿液中氯胺酮气相色谱和气相色谱-质谱检验方法》专题研究报告
- 2026年深圳中考语文论述类文本阅读试卷(附答案可下载)
- 2026年大学大二(口腔医学)口腔颌面外科学基础综合测试题及答案
- 2026年深圳中考数学三角形专项突破试卷(附答案可下载)
- 防灾减灾救灾题库及答案
- 电击伤的急救护理流程
- 2026年人教版英语九年级下册期中质量检测卷(附答案解析)
- 2026年人教版道德与法治七年级下册期末质量检测卷(附答案解析)
- (高清版)DB31∕T 1578-2025 微型消防站建设与运行要求
- 铁路项目部管理制度
- 物流仓储设备 检查与维护规程 第1部分:巷道堆垛机 征求意见稿
- 刮刮乐营销培训
- 2025-2030中国六氯乙硅烷行业需求量预测及前景动态研究研究报告
- 山东省临沂市沂水县2024-2025学年七年级上学期期末考试英语试题
- 铁路120型货车空气控制阀
- JBT 12530.2-2015 塑料焊缝无损检测方法 第2部分:目视检测
- JJG596-2012电子式交流电能表
- 定安海恒槟榔产业有限公司槟榔初加工项目 环评报告
- 如何系统评价和整合医学文献中的数据与证据
评论
0/150
提交评论