因此,正如问题所述,英特尔 8086 中 CS 和 IP 寄存器的目的是什么
我找到了这个解释:
代码段 (CS) 是一个 16 位寄存器,包含带有处理器指令的 64 KB 段地址。处理器使用 CS 段对指令指针 (IP) 寄存器引用的指令进行所有访问。CS 寄存器不能直接更改。CS 寄存器在远跳转、远调用和远返回指令期间自动更新。
这对于IP:
指令指针 (IP) 是一个 16 位寄存器。
我不太明白这基本上意味着什么,所以如果有人可以提供更“生动”的解释,那就太好了:)
物理地址由 2 个部分计算得出。i) 段地址。ii) 偏移地址。CS(代码段寄存器)用于寻址存储器的代码段,即存储器中存储代码的位置。IP(指令指针)包含内存代码段内的偏移量。因此,CS:IP 用于指向内存中代码的位置(即计算物理地址)。
由于指令指针 (IP) 是 16 位的,这意味着您只能拥有 64k 条指令 (2^16),即使在 80 年代也不多。因此,要扩展地址空间,您需要使用第二个寄存器来寻址 64k 块。您可以将cs:ip
其视为一个 32 位寄存器,然后它能够寻址 2^32 字节......即 4G,这是您在使用 32 位地址的处理器上获得的。8086 使用 20 位地址,因此您可以访问 1M 的内存。
接下来将执行的指令是内存地址等于:
16 * CS + IP
尽管寄存器只有 16 位宽(并且它还创建了两种不同的方式来对大多数地址进行编码),但这允许对 20 位内存进行寻址。
CS 的作用与其他段寄存器的作用类似。例如,DS
将数据访问(不指定另一个段寄存器)增加16 * DS
.
CS
修改 CS 的指令是:
CS 不能mov
像其他段寄存器一样被我修改。尝试使用 CS 的标准标识符对其进行编码,如果您编写以下代码,GNU GAS 2.24 不会抱怨:
mov %ax, %cs
执行时导致无效代码异常。
要观察 CS 的效果,请尝试将以下内容添加到引导扇区并在 QEMU 中运行它,如下所述https://stackoverflow.com/a/32483545/895245
/* $1 is the new CS, $1f the new IP. */
ljmp $1, $after1
after1:
/* Skip 16 bytes to make up for the CS == 1. */
.skip 0x10
mov %cs, %ax
/* cs == 1 */
ljmp $2, $after2
after2:
.skip 0x20
mov %cs, %ax
/* cs == 2 */
知识产权
每当执行一条指令时,IP 就会自动增加该指令的编码长度:这就是程序前进的原因!
IP 被修改 CS 的相同指令修改,以及这些指令的非远版本(更常见的情况)。
IP不能直接观察,所以比较难玩。检查这个问题的替代方案: Reading Program Counter direct
由于 8086 处理器使用 20 位寻址,我们可以访问 1MB 的内存,但 8086 的寄存器只有 16 位,所以要从内存中访问数据,我们将代码段寄存器和指令指针寄存器中存在的值结合起来生成一个物理地址,它是通过将 CS 的值向左移动 4 位然后将其与值 IP 相加来完成的
例子:
CS 的值为 1234Hex(十六进制)
IP 的值为 5678Hex
现在向左移动 4 位后 CS 的值是 12340Hex 然后加上 IP 值后它是 179B8Hex 这是物理地址
在汇编程序文本中编写 .code 后,该 .code 将指向 cs 值。文件中稍后或更早的任何命令都将按照 cs:ip 进行处理,其中 ip 是来自 cs 的偏移值。
当然,您必须记住,汇编编译器首先会将文本转换为机器代码指令。
IP 寄存器 - IP 是指令指针。它的作用与其他微处理器中的PC(程序计数器)相同,都是指向BIU单元要取的下一条指令送入EU单元。