2

在课堂上问这个,我想我明白但不确定,所以我想确认一下。

状态寄存器有 16 位,每个位都有一个标志。但是,我们的讲座幻灯片中提供的图像是否显示不同?

状态寄存器

该图像显示只有某些位实际上具有标志。这是否意味着实际上只有这些位被使用?剩下的只是饲料?

如果我的问题不清楚,我很抱歉,如果有人问,我可以尝试解释更多。

目前,我认为实际上只使用了 9 位?

4

1 回答 1

1

在文档中,它显示为“16 位寄存器”,因为它是寄存器的逻辑大小。

在实际实现(处理器的创建方式)中,它们通常只有 9 位。其他“位”是直接连接到接地引脚(或 +1.2V 或任何电压)的线路。这是因为内存很昂贵,如果你可以节省一些位,硬件更便宜(想想节省 5 位 x 1000 万个处理器……)

在较新的实现中,我想它们不会那么麻烦,尽管计算机会自动执行类似的操作,因此如果要将其始终保持为 0,就没有理由再拥有真正的一点内存。

所以作为一个程序员,就你而言,它是 16 位的。对于硬件工程师来说,它可能只有9 位。您只需要确保您仍然可以正确地将标志推送到堆栈上(其他 5 位将始终是一个已知值,在大多数情况下为零)。


更多细节:

要访问标志寄存器,作为程序员,您可以使用PUSHFPOPF

; read to AX
PUSHF
POP AX

; write from AX
PUSH AX
POPF

(作为上面关于 FUZxxl 注释的旁注,旧的 PUSHF 和 POPF 指令是 16 位的,新版本是 32 或 64 位的。这对于保持堆栈正确对齐很重要。)

正如 Ped7g 所提到的,虽然您可以在 AX 中放置任何随机值并执行PUSH+ POPF,但这不是一个好习惯。通常,当您想要更改没有指令的标志时,您可以:

PUSHF
POP AX
OR 10h       ; set flag A to 1
PUSH AX
POPF

更改标志的其他方法是使用某些指令。这直接在指令中定义。有一些指令,例如CLD直接STC清除或设置标志。还有其他诸如SBB调整借位和ADC进位(以及 N、Z、V 标志......)

最后,还有一些方法可以使用分支指令检查基本标志。在许多情况下,这与CMP指令一起使用(在较新的处理器上,标志可能会更改的原因有很多......)这允许您将寄存器与另一个值进行比较,如果它更小,更大,相等,更小则分支或等于、大于或等于,会产生溢出。因此,诸如JC读取 C 标志之类的指令如果为真(设置为 1)则跳转。

在较旧的处理器中,大多数标志都与分支链接。8086 为“算术”运算(以十进制进行加法和减法)添加了 A 标志,为“方向”添加了 D 标志(参见LOOPCX, MOVB)。

后来它为很多东西添加了许多其他标志,我不会在这里列出它们。其中一些对于了解是否存在某个指令很有用,从那时起我们就有了CPUID扩展指令,您需要了解有关 CPU 的所有信息,甚至可以在运行时对其进行修补。

于 2016-09-27T21:21:07.510 回答