3.2.CPU中的实模式

简介: 3.2.CPU中的实模式

3.2CPU中的实模式

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

3.2.1CPU的工作原理

cpu主体可以分为3个部分:控制单元,运算单元,存储单元


e84197f771294a1da0331e35dc00a0eb.png控制单元要取下一条待运行的指令,该指令的地址保存在程序计数器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中。


17122401bc9b47fc99d04f9e34501c19.png

在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。

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

36f38f931c0242bf9301192a71daf545.png


〈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,


c2c2363a79f24727ac4ca0574059c0b4.png

第 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 就是各种条件的分类, 每种条件有不同的转移指令。


8a89bc13c2674a9391d521edc9f0488d.png

a 表示 above

b 表示 below

c 表示 carry

e 表示 equal

g 表示 great

j 表示 jmp

l 表示 less

n 表示 not

o 表示overflow

p 表示parity


实模式小结

在实模式下, 用户程序和操作系统可以说是同一特权的程序, 因为实模式下没有特权级, 它处处和操作系统平起平坐, 所以可以执行一些具有破坏性的指令。

程序可以随意修改自己的段基址, 这样便在 1MB 的内存空间内不受阻拦, 可以随意访问任意物理内存,包括访问操作系统所在的内存数据这就给程序员开放了无限的自由, 程序员访问内存可以说是指哪打哪。

由于完全没有保护性可言, 用户程序甚至可以盖操作系统在内存中的映像, 整个计算机世界的和平全靠程序员的心情。


目录
相关文章
|
4月前
|
Linux Windows
获取cpu的核数
文章介绍了在不同操作系统上查看服务器CPU核数和线程数的多种方法,包括Windows系统使用命令窗口、任务管理器和WMIC命令,以及Linux系统使用`cat /proc/cpuinfo`和`lscpu`命令。
|
7月前
|
机器学习/深度学习 并行计算 图形学
CPU
CPU(中央处理器,Central Processing Unit)是计算机的核心部件,负责执行指令和处理数据。它是计算机的大脑,可以理解并执行程序中的指令。CPU 通常由一个或多个处理器核心组成,每个核心可以同时处理多个任务。
80 1
|
6月前
|
Linux
详细解读CPUAffinity(CPU亲合力)
详细解读CPUAffinity(CPU亲合力)
82 0
|
缓存
关于cpu的一些知识
关于cpu的一些知识
98 0
CPU和指令周期
转移指令时,需要判别转移是否成功,若成功则 PC 修改为转移指令的目标地址,否则下一条指令的地址仍然为PC自增后的地址
449 1
|
缓存 数据库 OceanBase
CPU使用率却达到了100%
CPU使用率却达到了100%
398 1
cpu是啥
CPU是指中央处理器(Central Processing Unit),是计算机中负责读取指令,对指令译码并执行指令的核心部件。CPU主要包括两个部分,即控制器、运算器,其中还包括高速缓冲存储器及实现它们之间联系的数据、控制的总线。
285 0
cpu是啥
|
缓存
完了!CPU一味求快出事儿了!
今天我们来为大家讲讲计算机的底层技术,CPU的那些事,快跟我一起去看看它又给我们整了什么活吧。
372 0
完了!CPU一味求快出事儿了!
|
监控 Linux
闲里偷忙的CPU
闲里偷忙
9438 0