CS、IP
CS
是代码段寄存器,用于存储当前代码段的基地址。
IP
是指令指针寄存器,用于存储当前指令的偏移地址。
CS:IP
组合起来形成一个完整的内存地址,CPU 会根据这个地址从内存中取指令并执行。
过程:16 位的 cs 和 16 位的 ip 通过位址加法器生成 20 位的地址,通过地址总线找到内存中的对应位置的内容,通过 16 位的数据总线运送指令(指令由若干个字组成)到指令缓冲器,执行指令内容后,将 ip + 指令长度。
举例:当然 CPU 状态,CS 中内容为 2000H,IP 中内容为 0000H。cs
32位、64位指的是什么?为什么说内存的每个地址存放一个字节(byte)的数据?32 位和 64位指处理器一次可以处理的数据宽度和它的寻址能力。它的寄存器宽度是32位,地址总线是32位。这里处理器一次能处理的数据宽度也称为 字长。而内存的每个地址存放的数据量还是1个字节。
jmp 指令
jmp 指令的实质是修改 cs、ip 寄存器的内容
jmp 段地址:偏移地址
,比如 jmp 2AE3:3
,其中段地址修改 cs,偏移地址修改 ip
jmp 寄存器
,比如 jmp ax
,是仅修改 ip 的内容
内存中一个字的存储
数据总线是 16 位的,cpu 一次处理的长度是 16 位,寄存器的长度为 16 位,内存中一个地址对应一个字节,是 8 位的。那么 16 位的字是如何在内存中存储呢?
16 位的字在内存中以 2 个连续字节进行存储,具体地,低位字节存在低地址单元,高位字节存放在高地址单元。(小端存储)
栈
CPU 如何知道一段内存空间被当作栈使用?如何定位栈顶单元?
对栈的操作是以字为单位的,用寄存器进行操作:栈段寄存器 ss
存放栈顶的段地址,栈顶指针寄存器 sp
存放栈顶的偏移地址
这样,栈顶指向的内存单元永远是 ss
段总结
三种段:数据段、代码段、栈段
数据段:段地址放在 DS 中,CPU 将对应位置的内容识别为数据
代码段:段地址放在 CS 中,段中的第一条指令的偏移地址放在 IP 中,CPU 将对应位置的内容识别为指令
栈段:段地址放在 SS 中,栈顶的偏移地址放在 SP 中,在进行栈操作时,CPU 就将我们定义的栈段当作栈空间来使用。
数据段和代码段如何区分?在内存中来看没有区别,只是 CPU 决定的,CPU 将 cs
指向的内存单元就当作代码段,将 ds:[address]就当作数据段
Jump
jump 的几种跳转方式:
call 和 ret
call + 标号
:call + 标号
,实现段内转移,类似jmp near ptr
标号;call far ptr
标号,实现段间转移,类似jmp far ptr
标号call + 寄存器号
:调用寄存器中存储的地址实现转移。call + 内存单元地址
:call word ptr 内存单元地址 (两个字节)
=push ip
+jmp word ptr 内存单元地址
;call dword ptr 内存单元地址(四个字节)
=push cs
+push ip
+jmp word ptr 内存单元地址
ret
:用栈中的数据,修改 IP 的内容,从而实现近转移,相当于 pop IPretf(return far)
:用栈中的数据,修改 CS 和 IP 的内容,从而实现远转移,相当于 pop IP,pop CS
标志寄存器
标志寄存器是按位起作用的,某些位有特殊的含义,有些位没有用到,不具有任何含义
8086 中标志寄存器位的含义
访问标志寄存器的方法?
pushf
将标志寄存器的值压栈
popf
从栈中弹出数据,送入标志寄存器中
对比 CF-进位标志
和 OF-溢出标志
?
CF
是对无符号数运算有意义的进/借位标志位
OF
是对有符号数运算有意义的溢出标志位
一个视为无符号数,一个视为有符号数,具体是要用哪个取决于你把数视为什么类型的数
cmp 指令
使用方式:cmp 操作对象 1,操作对象 2
cmp 是比较指令,功能相当于减法指令,只是不保存结果。结果执行后,对标志寄存器产生影响
条件转移指令
列出各个条件转移指令,以及它们表示的含义
记住英文缩写有助于记忆