assembly 为什么存在零标记?

lkaoscv7  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(120)

我理解进位和溢出标志的使用存在于算术中的错误检查,但为什么零标志对系统/程序员有用呢?

p1tboqfb

p1tboqfb1#

任何计算机都有一个非常常见的任务,就是比较两个整数(或指针)的大小,并根据结果进行条件跳转,这就是实现if (x < y)if (x == y)等高级结构的方法。
在x86上,如同在许多其它架构中一样,此任务被分解为两个指令:CMP或类似的指令来执行比较运算,而条件Jcc指令则执行跳转。CMP必须在CPU中有某种状态,才能将其结果传送给Jcc使用,这就是FLAGS寄存器的作用。
对于相等性的测试是这些操作中最基本的,因此应该存在根据CMP的两个操作数是否相等而设置的标志是有意义的。由于CMP实际上是隐藏的减法操作,因此这等效于询问减法的结果是否为零,这在硬件中很容易实现,通过对所有的位进行“或”运算,然后将一位的结果取反。这就是零标志。因为它基本上不需要花费什么,8086的设计者决定在几乎每个算术或逻辑指令之后,而不仅仅是在X1 M9 N1 X之后,以这种方式设置零标志。
那么“如果相等就跳转”就等同于“如果设置了零就跳转”。实际上,JEJZ只是同一条机器码指令的不同汇编助记符。
其他标准算术标志(进位、符号、溢出)也是以这种方式使用的。到目前为止,这是它们比任何一种错误检查更常见的用法。(实际上,许多编译语言并不进行这样的错误检查,而是在发生溢出时简单地忽略溢出。)例如,如果您希望跳转if AX < BX(其中寄存器中的值将被视为无符号),你可以从AX中减去BX,如果出现借位则跳转,这在x86上设置进位标志。2那么你的代码看起来就像CMP AX, BX / JC label。3汇编程序允许你使用JB而不是JC,这样你就可以把它看作是“如果低于则跳转”。4你也可以把它和零标志结合起来;如果要在AX <= BX时跳转,则写入CMP AX, BX ; JBE label,其中JBE将在设置进位或零标志中的 * 任一 * 时跳转。
符号和溢出标志类似地用于有符号比较,但规则稍微复杂一些。

ibps3vxo

ibps3vxo2#

这些标志远比仅仅从CMP中产生有用。“如果(!--x){...}
这可以很容易地用DEC/JZ对实现,而不需要任何中间CMP。

相关问题