简体   繁体   English

如何确定何时设置零标志,符号标志,溢出标志和进位标志?

[英]How to determine when zero flag, sign flag, overflow flag and carry flag are set?

The whole flag thing is confusing the heck out of me. 整个国旗的事情让我感到困惑。 The definitions on the web seem really plain. 网上的定义看起来很简单。 I can't seem to get a really good applicable explanation to all this. 我似乎无法对这一切得到一个非常好的适用解释。

According to their definitions, - carry: indicates an unsigned integer overflow - overflow: indicates a signed integer overflow - zero: an operation produced zero - sign: operation produced a negative number 根据它们的定义, - carry:表示无符号整数溢出 - 溢出:表示有符号整数溢出 - 零:操作产生零 - 符号:操作产生负数

So how in the world are the following sentences true? 那么世界上下面的句子怎么样呢? - The following instructions will set the Sign flag: (The answer here is 252 not a negative number. So why is the sign flag set?) - 以下说明将设置Sign标志:(这里的答案是252而不是负数。那么为什么设置了标志标志?)

mov al,0FEh
sub al,2
  • Adding 7Fh and 05h in an 8-bit register sets the Overflow flag.(The answer here is 132. It's not above 255 so why is there an overflow?) 在8位寄存器中添加7Fh和05h设置溢出标志。(这里的答案是132.它不高于255,那么为什么会出现溢出?)

  • Adding 0FFh and 05h in an 8-bit register does not set the Overflow flag.(the answer is 300 so how is there not an overflow flag on? It's above 256) 在8位寄存器中添加0FFh和05h不会设置溢出标志。(答案是300,那么如何没有溢出标志?它高于256)

  • Adding 5 to 0FBh in an 8-bit register sets the Zero flag (The answer here is 256, not 0. I understand the 8 bit can only hold 255 but where does the “0” come from? I just don't get it.) 在8位寄存器中添加5到0FBh设置零标志(这里的答案是256,而不是0.我理解8位只能容纳255但是“0”来自哪里?我只是不明白。)

Can someone please let me know what I'm doing wrong here and what the correct way to approach this is? 有人可以让我知道我在这里做错了什么以及正确的解决方法是什么? Thanks. 谢谢。

The answer here is 252 not a negative number. 这里的答案是252而不是负数。 So why is the sign flag set? 那么为什么要设置标志旗?

As unsigned it is 252, but unsigned can't have a sign, so the sign flag is only related to number handled as signed . 由于无符号它是252,但是无符号不能有符号,因此符号标志仅与处理为有符号的数字相关。 It doesn't matter how you handle it, the processor always handles it as signed with the sign flag. 无论你如何处理它,处理器总是处理它与sign标志签名。 So 252 is over 127, therefore it is negative in 2's complement and the sign bit is set. 因此252超过127,因此它在2的补码中是负的并且符号位被设置。

Adding 7Fh and 05h in an 8-bit register sets the Overflow flag.(The answer here is 132. It's not above 255 so why is there an overflow?) 在8位寄存器中添加7Fh和05h设置溢出标志。(这里的答案是132.它不高于255,那么为什么会出现溢出?)

As you said, overflow is set when a signed number would overflow. 正如您所说,当有符号数字溢出时会设置溢出。 A signed 8bit variable can go from -128 to 127. Therefore going from 127 to 132 is an overflow. 有符号的8位变量可以从-128到127.因此从127到132是溢出。

Adding 0FFh and 05h in an 8-bit register does not set the Overflow flag.(the answer is 300 so how is there not an overflow flag on? It's above 256) 在8位寄存器中添加0FFh和05h不会设置溢出标志。(答案是300,那么如何没有溢出标志?它高于256)

Again, overflow is signed overflow. 再次,溢出符号溢出。 This causes an unsigned overflow, so the carry bit will be set. 这会导致无符号溢出,因此将设置位。

Adding 5 to 0FBh in an 8-bit register sets the Zero flag (The answer here is 256, not 0. I understand the 8 bit can only hold 255 but where does the “0” come from? I just don't get it.) 在8位寄存器中添加5到0FBh设置零标志(这里的答案是256,而不是0.我理解8位只能容纳255但是“0”来自哪里?我只是不明白。)

As you said, 8 bits can go up to 255. After that it overflows and the lowest 8 bits are 0. So the result is zero and the zero bit is set. 正如你所说,8位可以达到255.之后它会溢出 ,最低的8位为0.因此结果为零,并且设置了零位。

Another excellent guide: Understanding Carry vs. Overflow conditions/flags . 另一个很好的指南: 了解Carry vs. Overflow条件/标志 It has some nice step-by-step examples with 4-bit numbers that make it easy to keep the whole thing in your head. 它有一些很好的分步示例,带有4位数字,可以很容易地保持整个过程。 It also explains that unsigned carry is what you're checking for when interpreting the bits as unsigned, while signed overflow is what you're checking for when interpreting the bits as signed. 它还解释了无符号进位是在将这些位解释为无符号时要检查的内容,而有符号溢出是在将这些位解释为有符号时要检查的内容。


Based on OP's comment: 基于OP的评论:

Does that mean that the zero flag is really turned on when the value of the 8 least significant bit is 0, and not just "when an operation produces 0" 这是否意味着当8个最低有效位的值为0时真正打开零标志,而不仅仅是“当操作产生0时”

The key thing you need to remember is that this is fixed-width integer arithmetic. 你需要记住的关键是这是固定宽度的整数运算。 In an 8bit register, 0xFF + 1 really does produce a 0. 在8位寄存器中,0xFF + 1确实产生0。

In mathematical terms, this is modular arithmetic , with a modulus of 2 8 for an 8bit operation. 在数学术语中,这是模运算8位运算的模数为2 8

So yes, ZF is set according to dst = (dst+src) % 0x100 . 所以是的, ZF是根据dst = (dst+src) % 0x100

It's designed this way because usually you just want to know whether the register is zero, whether you're counting up towards zero with inc on a register that started out negative, or whether you're counting down towards zero with a register that started positive. 它的设计方式是这样的,因为通常你只想知道寄存器是否为零,你是否计数到零,其中inc在一个开始为负的寄存器上,或者你是否用一个开始为正的寄存器向下计数到零。

You can still check CF==0 and ZF==1 to detect the case when you got a zero without carry. 您仍然可以检查CF==0ZF==1来检测没有进位时零的情况。 If ZF was only set when dst and CF were both zero, you'd often need another instruction to just test the result register. 如果仅在dstCF均为零时设置ZF则通常需要另一条指令来测试结果寄存器。


Having CF and ZF independent mean that the unsigned condition codes after a cmp or sub work like this: 具有CF和ZF独立意味着在cmpsub工作之后的无符号条件代码如下:

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).

I think if ZF could only be set when there wasn't a carry, you couldn't tell the difference between Above and Above-or-Equal . 我认为如果ZF只能在没有进位的情况下进行设置,那么你无法分辨出Above和Above-Equ-Equal之间的区别 So that's probably the most concrete reason for the design decision to not be made the way your first guess was going. 因此,这可能是设计决策不能按照您的第一次猜测的方式进行的最具体原因。

Here's one of the signed compare conditions: 这是签名的比较条件之一:

JLE     Jump  if less or equal (ZF=1 or SF ≠ OF).

The full set of conditions is in Intel's insn set reference manual (links in the tag wiki), under the jcc (jump if condition code) instruction listing. 完整的条件是在英特尔的insn set参考手册( 标签wiki中的链接)中,在jcc (跳转条件代码)指令列表下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM