存储器的保护(二)——《x86汇编语言:从实模式到保护模式》读书笔记19
接着上一篇博文说。
5.代码段执行时的保护
每个代码段都有自己的段界限。同栈段一个道理,有效界限和G位相关。
G=0:有效界限 = 描述符中的段界限
G=1:有效界限 = 描述符中的段界限值 * 0x1000 + 0xFFF
当处理器取指令的时候,偏移地址由EIP提供,EIP的范围应该在 [0,有效界限] 之间(为了说明问题,我就用数学上的闭区间表示了)。否则会引发异常。
对于本代码,代码段描述符中的界限值是0x1FF,G=0,那么有效界限=0x1FF,也就是说这个值就是段内最后一个允许访问的偏移地址。
再举一个例子,源文件中
71 mov dword [es:0x0b8000],0x072e0750 ;字符'P'、'.'及其显示属性
72 mov dword [es:0x0b8004],0x072e074d ;字符'M'、'.'及其显示属性
73 mov dword [es:0x0b8008],0x07200720 ;两个空白字符及其显示属性
74 mov dword [es:0x0b800c],0x076b076f ;字符'o'、'k'及其显示属性
这四行对应的.list文件如下
可以看到,第71行,mov dword [es:0x0b8000],0x072e0750 这条指令,其偏移地址为 0xB8~0xC2; 那么,要想这条指令顺利执行,定义代码段时,有效界限就要大于等于0xC2.当等于0xC2的时候,这条指令可以顺利执行,但是下一条指令的执行会引发异常。
也就是说,如果某条指令的偏移地址为M~N,那么这条指令被顺利执行的必要条件是集合[M,N]属于集合[0,代码段的有效界限]。(请原谅我借用集合来描述,可是我再也想不出什么简明的表达了)
6.数据访问时的保护
这里所说的数据段,特指向上扩展的数据段,有别于栈段和向下扩展的数据段。
访问数据段时,是否越界与操作数的长度有关。
对于向上扩展的数据段,有效界限的计算方法依然是:
G=0:有效界限 = 描述符中的段界限
G=1:有效界限 = 描述符中的段界限值 * 0x1000 + 0xFFF
举例来说,第74行
74 mov dword [es:0x0b800c],0x076b076f ;字符'o'、'k'及其显示属性
这条指令的目的是把0x076b076f写入偏移地址为0x0b800c~0x0b800f的4个存储单元。如果要成功写入,那么0x0b800c~0x0b800f必须在数据段的有效界限内。也就是要求:
[0xb800c, 0xb800f] 属于 [0, 上扩数据段的有效界限]
本代码中,数据段的有效界限值是0xFFFF_FFFF,也就是说可以访问4GB空间内的任何一个单元。
7.使用别名段访问代码段对字符排序
104;-------------------------------------------------------------------------------
105 string db 's0ke4or92xap3fv8giuzjcy5l1m7hd6bnqtw.'
106;-------------------------------------------------------------------------------
第105行,定义了一串字符。作者要对这串字符进行升序排序,其实“醉翁之意不在酒”——排序是假,使用别名段是真。因为代码段是不允许写入的,所以要修改代码段,就需要为之创建一个别名描述符。第33、34行,程序为代码段创建了一个可读写的数据段描述符。也就是说,我们可以把代码段当成数据段来用。
33 mov dword [ebx+0x18],0x7c0001ff ;基地址为0x00007c00,512字节
34 mov dword [ebx+0x1c],0x00409200 ;粒度为1个字节,数据段描述符,可读写
第59、60行,把这个别名段的选择子加载到DS
59 mov eax,0x0018
60 mov ds,eax
这里我们用冒泡排序法,虽然这个方法效率低,但是很适合初学者入门。关于冒泡排序的知识,请参考其他资料。
为了说明问题,我绘制了一张图,假如一共有5个数,要把它们从左至右按照升序排列,示意图如下。
每比较一次,就把较大的数放在右边。那么第一次外循环后,最大的数就冒到了最右边;第二次外循环后,第二大的数冒到了从右边数第二个位置;……
如果N个数参加排序,那么外循环需要(N-1)次。第1次需要(N-1)次比较,第2次需要(N-2)次比较,……第(N-1)次需要一次比较。
说了这么多,我就是想说清楚代码。
76 ;开始冒泡排序
77 mov ecx,pgdt-string-1 ;遍历次数=串长度-1
78 @@1:
79 push ecx ;32位模式下的loop使用ecx
80 xor bx,bx ;32位模式下,偏移量可以是16位,也可以
81 @@2: ;是后面的32位
82 mov ax,[string+bx]
83 cmp ah,al ;ah中存放的是源字的高字节
84 jge @@3
85 xchg al,ah
86 mov [string+bx],ax
87 @@3:
88 inc bx
89 loop @@2
90 pop ecx
91 loop @@1
第77行,刚开始,ECX保存着外循环的次数(字符数-1)。
79行把ECX压栈是因为内循环也要用这个值(这个值就是本循环比较的次数),而且在内循环中,这个次数会变化。为了不破坏外循环的次数,所以要压栈保存。
第81~89行,是内循环,完成字符对比的工作。首先一次性读入2个字符到AX中,AL中存放的是前一个(低地址处的)字符,AH中存放的是后一个(高地址处的)字符,如果前者大,则交换AL和AH的内容,然后把AX重写入原来的存储单元。接下来,BX加1,以指向下一个字符。
93 mov ecx,pgdt-string
94 xor ebx,ebx ;偏移地址是32位的情况
95 @@4: ;32位的偏移具有更大的灵活性
96 mov ah,0x07
97 mov al,[string+ebx]
98 mov [es:0xb80a0+ebx*2],ax ;演示0~4GB寻址。
99 inc ebx
100 loop @@4
101
102 hlt
排序完毕后,第93~100,用于显示最终的排序结果。
第98行表示从显存的第2行第1列(0xb8000 + 0xa0(=160D) = 0xb80a0)开始显示字符串。当EBX=0、1、2……时,对应的地址是0xb80a0、0xb80a2、0xb80a4……(使用比例因子就是这么方便),注意,“0xb80a0
+ ebx * 2”,这个表达式的值是在指令执行时,由处理器计算出来的。
(12章完)
存储器的保护(二)——《x86汇编语言:从实模式到保护模式》读书笔记19的更多相关文章
- ASM:《X86汇编语言-从实模式到保护模式》第10章:32位x86处理器的编程架构
★PART1:32位的x86处理器执行方式和架构 1. 寄存器的拓展(IA-32) 从80386开始,处理器内的寄存器从16位拓展到32位,命名其实就是在前面加上e(Extend)就好了,8个通用寄存 ...
- ASM:《X86汇编语言-从实模式到保护模式》第11章:进入保护模式
★PART1:进入保护模式 1. 全局描述符表(Global Descriptor Table,GDT) 32位保护模式下,如果要使用一个段,必须先登记,登记的信息包括段的起始地址,段的 ...
- ASM:《X86汇编语言-从实模式到保护模式》第8章:实模式下硬盘的访问,程序重定位和加载
第八章是一个非常重要的章节,讲述的是实模式下对硬件的访问(这一节主要讲的是硬盘),还有用户程序重定位的问题.现在整理出来刚好能和保护模式下的用户程序定位作一个对比. ★PART1:用户程序的重 ...
- ASM:《X86汇编语言-从实模式到保护模式》第16章:Intel处理器的分页机制和动态页面分配
第16章讲的是分页机制和动态页面分配的问题,说实话这个一开始接触是会把人绕晕的,但是这个的确太重要了,有了分页机制内存管理就变得很简单,而且能直接实现平坦模式. ★PART1:Intel X86基础分 ...
- ASM:《X86汇编语言-从实模式到保护模式》第12章:存储器的保护
12章其实是11章的拓展,代码基本不变,就是在保护模式下展开讨论. ★PART1:存储器的保护机制 1. 修改段寄存器的保护 当执行把段选择子传到段寄存器的选择器部分的时候,处理器固件在完成传送之前, ...
- ASM:《X86汇编语言-从实模式到保护模式》第15章:任务切换
15章其实应该是和14章相辅相成的(感觉应该是作者觉得14章内容太多了然后切出来了一点).任务切换和14章的某些概念是分不开的. ★PART1:任务门与任务切换的方法 1. 任务管理程序 14章的时候 ...
- ASM:《X86汇编语言-从实模式到保护模式》第9章:实模式下中断机制和实时时钟
中断是处理器一个非常重要的工作机制.第9章是讲中断在实模式下如何工作,第17章是讲中断在保护模式下如何工作. ★PART1:外部硬件中断 外部硬件中断是通过两个信号线引入处理器内部的,这两条线分别叫N ...
- ASM:《X86汇编语言-从实模式到保护模式》第14章:保护模式下的特权保护和任务概述
★PART1:32位保护模式下任务的隔离和特权级保护 这一章是全书的重点之一,这一张必须要理解特权级(包括CPL,RPL和DPL的含义)是什么,调用门的使用,还有LDT和TSS的工作原理(15章着重 ...
- ASM:《X86汇编语言-从实模式到保护模式》5-7章:汇编基础
第5-7章感觉是这一本书中比较奇怪的章节,可能是作者考虑到读者人群水平的差异,故意由浅入深地讲如何在屏幕上显示字符和使用mov,jmp指令等等,但是这样讲的东西有点重复,而且看了第六,第七章以后,感觉 ...
随机推荐
- Android-动态添加控件到ScrollView
在实际开发过程中,会需要动态添加控件到ScrollView,就需要在Java代码中,找到ScrollView的孩子(ViewGroup),进行添加即可. Layout: <?xml versio ...
- oracle通过job执行procedure
1. 先创建一个FUNCTION CREATE OR REPLACE FUNCTION GET_TIMEOUT_PROGRAM(i_customerNo IN TK_CUST_PROG_D.CUSTO ...
- elasticsearch(0.90.10)安装配置+超多插件!!
一)安装elasticsearch 1)下载elasticsearch-0.90.10,解压,运行\bin\elasticsearch.bat (windwos) 2)进入http://localho ...
- xshell无法连接Ubuntu的解决办法
使用workstations14安装完Ubunu后,网络连接方式为NAT模式(N):用于共享主机的IP地址 此时想用xshell连接此虚拟机但是提示连接失败,但是宿主机和虚拟机互相都能ping通,且虚 ...
- .Net Core使用OpenXML导出,导入Excel
导出Excel是程序很常用到的功能,.Net Core可以借助Open-XML-SDK来导出Excel. Open-XML-SDK open-xml-sdk是是微软开源的项目.Open XML SDK ...
- C# redis 的简单应用
region 准备参数 var connStr = "localhost:6379,password="; var db = 2; SiteRedisHelper redisHel ...
- 云课堂Android模块化实战--如何设计一个通用性的模块
本文来自 网易云社区 . 如何设计一个通用性的模块 前言 每个开发者都会知道,随着项目的开发,会发现业务在不断壮大,产品线越来越丰富,而留给开发的时间却一直有限,在有限的时间,尽快完成某个功能的迭代. ...
- Perl+OpenGL 重绘inkscape生成的svg矢量图
Perl+OpenGL 重绘inkscape生成的svg矢量图 还不够完善,先挖个坑,后面慢慢填 Code: [全选] [展开/收缩] [Download] (Untitled.pl) =info A ...
- 一键生成ssl自签名证书脚本
#!/bin/bash -e # * 为必改项 # * 更换为你自己的域名 CN='' # 例如: demo.rancher.com # 扩展信任IP或域名 ## 一般ssl证书只信任域名的访问请求, ...
- “全栈2019”Java第六十二章:接口与常量详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...