整个国旗的事情让我感到困惑。网上的定义看起来很简单。我似乎无法对这一切得到一个非常好的适用解释。
根据他们的定义, - carry:表示无符号整数溢出 - overflow:表示有符号整数溢出 - 零:操作产生零 - 签名:操作产生负数
那么世界上下面的句子怎么样呢? - 以下说明将设置Sign标志:(这里的答案是252而不是负数。那么为什么设置了标志标志?)
mov al,0FEh
sub al,2
在8位寄存器中添加7Fh和05h会设置溢出标志。(这里的答案是132.它不高于255,为什么会出现溢出?)
在8位寄存器中添加0FFh和05h不会设置溢出标志。(答案是300,那么如何没有溢出标志?它高于256)
在8位寄存器中添加5到0FBh设置零标志(这里的答案是256,而不是0.我理解8位只能保持255但是“0”来自何处?只是不明白。)
有人可以让我知道我在这里做错了什么以及正确的方法是什么? 感谢。
答案 0 :(得分:7)
这里的答案是252而不是负数。那么为什么要设置标志标志?
作为 unsigned ,它是252,但是unsigned没有符号,因此sign标志仅与作为 signed 处理的数字相关。无论你如何处理它,处理器总是处理它与sign标志签名。因此252超过127,因此它在2的补码中是负的,并且符号位被设置。
在8位寄存器中添加7Fh和05h设置溢出标志。(这里的答案是132.它不高于255,那么为什么会出现溢出?)
正如您所说,当签名号码溢出时,会设置溢出。带符号的8位变量可以从-128到127.因此,从127到132是溢出。
在8位寄存器中添加0FFh和05h不会设置溢出标志。(答案是300,那么如何没有溢出标志?它高于256)
同样,溢出是签名溢出。这会导致无符号溢出,因此将设置进位位。
在8位寄存器中添加5到0FBh设置零标志(这里的答案是256,而不是0.我知道8位只能容纳255但是“0”来自哪里?我只是'得到它。)
正如你所说,8位可以达到255.之后溢出,最低的8位为0.因此结果为零,并且设置了零位。
答案 1 :(得分:1)
另一本优秀指南:Understanding Carry vs. Overflow conditions/flags 。它有一些很好的分步示例,带有4位数字,可以很容易地保持整个过程。它还解释了无符号进位是在将这些位解释为无符号时要检查的内容,而有符号溢出是在将这些位解释为有符号时要检查的内容。
基于OP的评论:
这是否意味着当8个最低有效位的值为0时真正打开零标志,而不仅仅是“当操作产生0时”
您需要记住的关键是这是固定宽度整数算术。在8位寄存器中,0xFF + 1确实产生0。
在数学术语中,这是modular arithmetic,对于8位操作,模数为2 8 。
是的,ZF
是根据dst = (dst+src) % 0x100
设置的。
这是以这种方式设计的,因为通常你只想知道寄存器是否为零,是否在开始为负的寄存器上用inc
计数到零,或者你是否正在倒计时注册表开始为正数,为零。
您仍然可以检查CF==0
和ZF==1
,以便在没有携带时获得零的情况下进行检测。 如果ZF
仅在dst
和CF
均为零时设置,则通常需要另一条指令来测试结果寄存器。
CF和ZF独立意味着cmp
或sub
后的无符号条件代码如下所示:
JA Jump if above (CF=0 and ZF=0).
JAE Jump if above or equal (CF=0).
JB Jump if below (CF=1).
JBE Jump if below or equal (CF=1 or ZF=1).
JC Jump if carry (CF=1).
JE Jump if equal (ZF=1).
我认为如果ZF只能在没有进位时设置,你就无法分辨出Above和Above-or-Equal 之间的区别。因此,设计决策 not 的最具体原因可能就是你的第一次猜测。
以下是签名比较条件之一:
JLE Jump if less or equal (ZF=1 or SF ≠ OF).
完整的条件是英特尔的insn set参考手册(x86标签wiki中的链接),在jcc
(条件代码跳转)指令列表下。