状态寄存器实际使用了多少位(8086)

时间:2016-09-27 20:42:06

标签: assembly cpu-architecture cpu-registers x86-16 status-register

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

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

Status register

图像显示只有某些位实际上有标志。这是否意味着实际上只使用了那些位?其余的那些只是饲料?

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

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

1 个答案:

答案 0 :(得分: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

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

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

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

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