3.2CPU中的实模式

实模式是相对于保护模式的叫法。指的是8086CPU的工作环境,工作方式,工作状态。

3.2.1CPU的工作原理

cpu主体可以分为3个部分:控制单元,运算单元,存储单元
控制单元要取下一条待运行的指令,该指令的地址保存在程序计数器PC(=cs:ip)上,,将地址送上地址总线上,CPU根据地址将指令保存在指令寄存器(IR)上。先确定操作码再确定操作数。如果操作数在内存中就将相应的操作数从内存中取回放入自己的存储单元,这样操作码有了,操作数有了操作控制器给运算单元下指令。进行运算。

3.2.2实模式下的寄存器

CPU中的寄存器大致分为两类:
1.内部使用的寄存器:GDTR(全局描述符寄存器),IDTR(中断描述符表寄存器),LDTR(局部描述符表寄存器),TR(任务寄存器)CR0-3(控制寄存器),IP(指令指针寄存器),flags(标志寄存器),DR0-7调试寄存器。
其中全局描述符表寄存器 GDTR, 通过 Igdt 指令为其指定全局描述符表的地址及偏移量。
中断描述符表寄存器 IDTR通过 1idt指令为其指定中断描述符表的地址
局部描述符表寄存器 LDTR用gdt指令为其指定局部描述符表ldt
任务寄存器TR,用 ltr 指令为其指定一个任务状态段tss。
flags 寄存器,系统提供了 pushf和popf指令, 分别用于将 flags 寄存器的内容压入栈, 将栈中内容弹到 flags 寄存器
ldt和tss 都位于 gdt中。


在CPU内部寄存器都是十六位的,但是如何才能表示20位地址呢?
通过将16位段基址左移4位变成20位(形成段地址),后4位由段内偏移得到。超出范围就进行回卷操作(跟循环队列相似)。

实模式下的CPU内存寻址方式

(1 )寄存器寻址:最直接的寻址方式就是寄存器寻址, 它是指 “数″ 在寄存器中, 直接从寄存器中拿数据就
(2) 立即数寻址:操作数存在指令中,直接就能使用。
(3) 内存寻址:操作数在内存中的寻址方式。
在第三种内存寻址中又分为
(l〉 直接寻址:直接寻址。 就是将直接在操作数中给出的数字作为内存地址, 通过中括号的形式告诉 CPU, 取此地址中的值作为操作数。mov ax, [0x1234]
(2) 基址寻址:基址寻址就是在操作数中用 bx 寄存器或寄存器作为地址的起始, 地址的变化以它为基础。
(3) 变址寻址:变址寻址其实和基址寻址类似,只是寄存器由bx、bp换成了 si和di。si是指源索引寄存器〈somee index), di是指目的索引寄存器 (destinationindex)e 两个寄存器的默认段寄存器也是 ds
(4) 基址变址寻址:基土止寄存器 bx或bp 加一个变址寄存器si或di。
mov [bx+d土],ax
add [bx+si],ax

这里举一个使用bp寄存器的应用:重点在堆栈框架

int a = O;
function(int b, int c) {int d;
}
a++;


〈1) 调用 function(l,2) 按照 Ci吾言调用规范 参数入栈的顺序从右到左= 会先压入 2, 再压入l
每个参数在栈中各占 4字节
〈2〉 栈中再压入 负nction的返回地址, 此时栈顶的值是执行 “a忏 相关指令的地址。
下面是堆栈框架的指令
〈3) pushebp’ 将ebp压入栈 栈中备份ebp 的值, 占用 4字节
〈4〉 movebp, esp 将esp 的值复制到ebp, ebp 作为堆栈框架的基址, 可用于对栈中的局部变量和其
他参数寻址此时的 ebp 便是栈中局部变量的分界线。 在这之后z esp将自减一定的值为局部变量在栈中分配空间,该值取决于所有局部变量空间大小的总和。
〈5〉sub esp,4; 由于函数 function 中有局部变量 d, 局部变量是在栈中存放的, 故esp要预留出4字节,
专门给变量d使用。
在执行上面五步之后就形成上图所示的堆栈框架。
栈中数据的布局如图3-8 所示。
在函数执行完调用函数的时候执行6,7步。
(6〉 函数结束后跳过局部变量的空间= movesp,ebp。 低地址
(7〉 恢复 ebp 的值= pop ebp。
总结一下:主要还是ebp寄存器做到了一个分界线的作用。标明局部参数。

3.2.6实模式下的ret

ret (return) 指令的功能是在栈顶 (寄存器 ss: sp 所指向的地址) 弹出2字节的内容来替换庄寄存器。
retf (return far) 是从栈顶取得4字节, 栈顶处的2字节用来替换IP寄存器, 另外的2字节用来替换CS 寄存器。
call和ret是一对配合, 用于近调用和近返回, callfaI和retf是一对配合, 用于远调用和远返回。

3.2.7实模式下的call

call指令调用函数有四种方式。
1.16 位实模式相对近调用
call 指令所调用 目标函数和当前代码段是同一个段, 即在同一个 64KB 的空间内, 所以只给出段内偏移地址就好了, 不用给出段基址。
指令格式是 call near 立即数地址,例如call near prog_name 不过千万不要误会编译
后的操作数是目标函数proc_皿me 的绝对地址, 在编译后的机器码的操作数中, 它是call指令相对于目标地址的偏移量’ 是个地址差。就是说, 假如proc_name被编译器分配的地址是0x1234, call指令最终的操作数并不是 0x1234, 而是目标地址减去当前 call 指令的地址,所得的差再减去此指令的长度3, 最终的结果才是 call相对近调用指令的操作数。
2.16位实模式间接绝对近调用
“间接” 是指目标函数的地址并没有直接给出, 地址要么在寄存器中, 要么在内存中, 总之不以立即 数的形式出现。
“绝对″ 是指目标函数的地址是绝对地址’ 不像 “16 位相对近调用″ 中的那样是相对地址。
指令的一般形式是 “call 寄存器寻址” 或 “call 内存寻址”。
3.16 位实模式直接绝对远调用
直接就是操作数在指令中直接给出, 是立即数。
“远” 就意指要跨段啦, 目标函数和当前指令不在同一个段中。
call far 段基址 〈立即数) = 段内偏移地址 (立即数〉
4.16 位实模式间接绝对远调用
段基址和段内偏移地址在内存中。
16 位间接绝对远调用指令格式是= call far 内存寻址

3.2.8实模式下的jmp

jmp转移指令只要更新 CS: IP寄存器或只更新IP寄存器就好了, 不需要保存它们的值, 所以跳到新的地址后没办法再回来, 它属于 “一去不回头″ 地去执行新指令。
jmp可以分为近转移和远转移
1.l6位实模式相对短转移
常用的jmp$。 指令格式:jmp short 立即数地址
short 关键字指明了这次指令执行的是短转移,后面的立即数的范围在-128~127上
跳转的范围是1字节的有符号数所表示的范围,即-128~127.
在jmp 的相对短转移形式中也是一样的,操作数也要经过编译器转换,其转换方法和call 的相对近调用是一样的原理,即用跳转后的目标地址减去当前地址,所得的差再减去此种jmp指令的大小2字节,最终的结果便是此jmp相对短转移的操作数。
针对上面的立即数范围的限制有以下解决方案。
(l) 将第2行jmp后的shon去掉, 改成near。
(2) 第 2行jmp后什么都不写, 让nasm编译器来自动判断, 用shon, 还是 near。

2.16位实模式相对近转移
指令格式是jmpnear 立即数地址,相对近转移和相对短转移相比, 就是操作数范围增大了, 由 8位宽度变成了 16 位宽度, 操作数依然是地址相对量, 可正可负, 范围是-32768~32767。
指令中的立即数地址也要经过编译器转换为地址偏移量, 再变成机器指令中的操作数。操作数=目标地址-当前指令地址-3。
相对这个字表明了操作数是一个地址增量,CPU需要将其还原成绝对地址。绝对地址=操作数+IP
3.16 位实模式间接绝对近转移
同上一个 “jmp 相对近转移” 相比, 本 “间接绝对近转移″ 其目标地址是绝对地址, 并且未在指令中直接给出, 存在寄存器或内存中。
“间接绝对近转移″ 就是指段内转移, 转移的地址是16位宽度, 也就是2字节, 地址要么在寄存器中, 要么在内存中。
4.16位实模式直接绝对远转移
“直接” 是指操作数不仅是立即数, 而且 CPU直接拿来就用, 不用再转换。
“绝对” 是指提供的操作数是绝对地址。
“远” 是指目的地址和当前指令不是一个段,有跨段的需求, 所以要操作数要包括新的段基址和段内偏移。
5.16 位实模式间接绝对远转移
和上面一个相比操作数放在内存
在指令中用关键字 far, 即前两个字节是段内偏移地址, 后两个字节是段基址。
若不指定, 则和第三种的 “间接绝对近转移” 一样, 只在内存处取2字节。
jmp far 内存寻址。
以上是无条件转移指令

3.2.9标志寄存器flags

实模式下标志寄存器是 16 位的 flags, 在 32 位保护模式下’ 扩展 (extend) 了标志寄存器, 成为 32位的 fags。
efags寄存器兼容fags 寄存器, 还是给各位看官呈上 efags,

第 0位的是 CF 位, 即 Carry Flag, 意为进位。 运算中, 数值的最高位有可能是进位, 也有可能是借位, 所以 carry 表示这两种状态。 不管最高位是进位, 还是借位, CF 位都会置 1, 否则为 0。 它可用于检测无符号数加减法是否有溢出, 因为 CF为l时, 也就是最高位有进位或借位, 肯定是溢出。
第1、 3、 5、 15 位没有专门的标志位, 空着占位用。
第 2位为PF位, 即 ParityFlag, 意为奇偶位。 用于标记结果低8位中 1 的个数, 如果为偶数, PF位为1, 否则为 0。 注意啦, 是最低的那8位, 不管操作数是 16 位, 还是 32 位。 奇偶校验经常用于数据传输开始时和结束后的对比, 判断传输过程中是否出现错误。
第4位为AF位, 即AuxiHary carry Flag, 意为辅助进位标志, 用来记录运算结果低4位的进、借位情况, 即若低半字节有进、 借位, AF为 l, 否则为 0。 _
第6位为ZF位, 即 ZeIoFlag, 意为零标志位。 若8十算结果为 0, 此标志为l, 否则为 0。
第7位为 SF 位, 即SigalFlag’ 意为符号标志位。 若运算结果为负, 则SF 位为 l, 否则为 0。
第8位为TF位, Trap Flag, 意为陷阱标志位。 此位若为1, 用于让 CPU 进入单步运行方式, 若为 0 则为连续工作的方式。 平时我们用的debug程序, 在单步调试时, 原理上就是让TF位为1。 可见软件上的很多功能,必须有硬件的原生支持才能得以实现。
第 12~13 位为 IOPL, 即 Input Output Privilege Level, 这用在^有特权级概念的 CPU 中。 有 4 个任务 特权级′ 即特权级0、 特权级l、 特权级2和特权级 3。 故IoPL要占用2位来表示这4种特权级。 如果您 对此感到迷茫, 不用担心, 这些将来咱们在保护模式下也得实践。

3.2.10有条件转移

有条件转移不是简单的一个指令, 它是一个指令族, 我们在此简单称j魅。 如果条件满足, jxx 将会跳转到指定的位置去执行, 否则继续顺序地执行下一条指令。
格式为 jxx 目标地址。 若条件满足则跳转到目标地址, 否则顺序执行下一条指令。
进行条件转移, 所谓的条件就是判断上一条指令的结果是否满足某方面或某些方面, 能够影响标志位的指令才能被其后的条件指令用作条件。 所以条件转移指令一定得在某个能够影响标志位的指令之后进行。 也就是说, 每执行一条指令, 标志寄存器中的相应位都会记录这条指令所带来的变化。 所以说条件转移指令, 判断的就是上一条指令对标志位的 “影响”, 这些 “影响″ 就是条件。当满足条件的时候就执行条件转移指令。
条件转移指令中所说的条件就是指标志寄存器中的标志位。 jxx中的xx 就是各种条件的分类, 每种条件有不同的转移指令。

a 表示 above
b 表示 below
c 表示 carry
e 表示 equal
g 表示 great
j 表示 jmp
l 表示 less
n 表示 not
o 表示overflow
p 表示parity

实模式小结

在实模式下, 用户程序和操作系统可以说是同一特权的程序, 因为实模式下没有特权级, 它处处和操作系统平起平坐, 所以可以执行一些具有破坏性的指令。
程序可以随意修改自己的段基址, 这样便在 1MB 的内存空间内不受阻拦, 可以随意访问任意物理内存,包括访问操作系统所在的内存数据这就给程序员开放了无限的自由, 程序员访问内存可以说是指哪打哪。
由于完全没有保护性可言, 用户程序甚至可以盖操作系统在内存中的映像, 整个计算机世界的和平全靠程序员的心情。

3.2.CPU中的实模式相关推荐

  1. [操作系统真象还原3]cpu的8086实模式、显卡、硬盘

    本文为读书笔记,是对书中自己认为重要的点进行简要摘录和总结,如需要更进一步了解,还是推荐看原书,作者讲的非常详细. 原书:郑钢 操作系统真象还原 文章目录 1:cpu8086实模式 1.1:cpu工作 ...

  2. 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16...

    一.Intel 32 位处理器的工作模式 如上图所示,Intel 32 位处理器有3种工作模式. (1)实模式:工作方式相当于一个8086 (2)保护模式:提供支持多任务环境的工作方式,建立保护机制 ...

  3. 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16

    一.Intel 32 位处理器的工作模式 如上图所示,Intel 32 位处理器有3种工作模式. (1)实模式:工作方式相当于一个8086 (2)保护模式:提供支持多任务环境的工作方式,建立保护机制 ...

  4. (实模式+保护模式)模式切换的过程步骤(代码+文字解析)

    [0]写在前面 文末的个人总结是干货,前面代码仅供参考的,且source code from orange's implemention of a os. ; ==================== ...

  5. x86从实模式到保护模式 pdf_【自制操作系统04】从实模式到保护模式

    通过前三章的努力,我们成功将控制权转交给了 loader.asm 这个程序.具体说就是 bios 通过加载并跳转到 0x7c00(IMB大叔们定的) 把控制权转交给了我们操作系统的第一个汇编程序 mb ...

  6. X86汇编语言从实模式到保护模式08:中断和动态时钟显示

    目录 1. 外部硬件中断 1.1 概述 1.2 外部硬件中断分类 1.2.1 概述 1.2.2 不可屏蔽中断 1.2.3 可屏蔽中断 1.3 中断控制器 1.3.1 引入中断控制器的原因 1.3.2 ...

  7. 【操作系统 3.了解实模式与保护模式的区别】

    一.实模式与保护模式鸟瞰 我这人喜欢直面问题,其实本章只需要搞明白三个主要问题就行了, 什么是实模式和保护模式, 实模式与保护模式的区别是什么, 怎么进入保护模式. 我先来简单阐述下这三个问题 什么是 ...

  8. 实模式、保护模式和虚拟8086模式

    参考自:实模式与保护模式解惑之(一)--二者的起源与区别(河西无名式) 概述:实模式和保护模式是处理器发展的两个非常重要的阶段.这两个模式下的编程也有着显著的不同,弄明实模式与保护模式的区别是理解操作 ...

  9. 06.实模式进入保护模式

    简介 上一节我们实现了从内核加载器中加载其它扇区代码并执行,但始终工作在实模式状态下.内存寻址方式和8086相同,由16位段寄存器的内容乘以16(10H)当做段基地址,加上16位偏移地址形成20位的物 ...

  10. CPU实模式和保护模式、全局描述符表GDT、Linux内核中GDT和IDT的结构定义

    一 计算机实模式和保护模式 实模式 在实模式下,内存被限制为仅有1M字节(220 字节).有效的地址从00000到FFFFF (十六进制). 这些地址需要用20位的数来表示.一个20位的数不适合任何一 ...

最新文章

  1. php mongodb execute,php简单操作mongodb
  2. Google App Engine 学习和实践
  3. 基于Android的浮动组件,可以用于应用中的新功能展示等等。
  4. Maven-EclipseEE使用Maven构建Java web项目从0到1
  5. 数学学渣的福利,看看图就能学会的机器学习
  6. 阿里docker安装mysql_docker安装mysql
  7. 数据类型字符串得索引及切片
  8. 8.0/9.0 Email 设置
  9. Spark初识-Spark基本架构概览使用
  10. 菊长说丨一文读懂MySQL4种事务隔离级别
  11. Java中的泛型全解析(二)
  12. (已更新)婚礼类小程序前端界面模板源码
  13. 使用MongoVUE
  14. python写入文件取消自动换行
  15. ORID方法在敏捷中的利用,关于敏捷迭代
  16. python停止程序_如何停止python程序
  17. Cut the Cake!题解
  18. oracle自带加加解密工具的使用一例
  19. c语言调用calculate函数,关于c语言中int calculate函数求解。谢谢
  20. MySQL NDB Cluster部署方案与实践

热门文章

  1. 小象学院 nlp 自然语言处理项目实战
  2. OpenCV的配置过程和可能遇到的问题
  3. 人一生要读的60本书(经典读书计划)
  4. 查询失败,后台服务器运行错误,添加网络打印机错误?怎么处理?Windows 无法连接到打印机。 服务器打印后台处理程序服务没有运行。...
  5. C语言练习作品 - U盘病毒模拟
  6. 接口管理工具Rap的安装
  7. c语言日历显示系统,C语言实现显示日历
  8. ios模拟器装ipa包_用iOS模拟器安装App的方法
  9. C#递归算法使用案例——画树
  10. 安装Android adb驱动