While Wilson and Janka already explain the arithmetic and 6502 related (*1) implication, I somehow get the feeling this question is not about the 6502
Behavior of the zero and negative/sign flags on classic instruction sets
but rather some generic, absolute meaning.
I'm very curious, cross-architecturally, how this has varied.
There is no variation, as there is no absolute meaning (*2) what Z should be, or that Z even stands for Zero.
So short answer:
There is no one size fits all. One has to look at every ISA on its own, as similar naming will may mean different things based on different assumptions for each architecture.
[Insert...
If at all, one may think of it as with languages. There can be words with similar meanings in different languages, but they rarely overlap exactly, even for simple things. Even if these words sound (almost) the same and their meaning seems quite similar, they are not - like for Z and flags.
Think of English 'Hound' and German 'Hund'. Both are about a dog, but while the German Hund means dog in general, English Hound is a subset of dog. Much like the Z80 Z flag is a subset of the 6502 Z flag, isn't it? (*2)
...back to CPUs and conditions]
Long Answer:
There are CPUs
- without flags at all - like some VLIW
- without flags but relational tests - like DEC ALPHA
- without flags but conditional traps
- with condition codes instead of flags - like IBM /360ish (it can't get more classic :))
- with flags much like 6502 or Z80 but many different compositions
(I guess with some thinking the list may be extended many more ways.)
As well as combinations thereof, where MIPS is a great example (*3) again:
Bottom line: CPU architectures with flags are just one case of many, rather a minority among all designs - that is, unless we count the number of delivered devices (even considering MIPS working hard in many cheap consumer products won't change this).
The reason is rather simple, as using flags is the least effort hardware wise. Basically flags are just cached output signals of the ALU (like on Z80) sometimes enriched by additional test logic(*4). They only make very basic observations available to software. Fine as long as there are only a few and rather basic 'notifications' to be made about the result of an operation. But as soon as we leave the very basic domain and the number of resulting conditions may become quite crowded, hard to be handled in a systematic way - even less in similar ways across architectures.
While a 'simple' Zero or the mentioned Negative introduces only minor differences between architectures, it gets quite messy when the meaning to be transported gets more and more complex. Just take a look at the handling of signed numbers and overflow in 8080 vs. 6502. Here several new flags with only minor overlap are introduced. And this is still only integer arithmetic.
Architectures offering a more diverse set of operations (*5) usually drop the whole flag part and go either for generation of a more abstract operation result, like a condition code, to be used on a case-by-case basis(*6), or move the whole result/condition testing away from the operation completely (like MIPS, Alpha)
Doing away with flags can
- simplify software structure and
- improve performance
*1 - Well, both contain part of the workings within a 6502. The signal for Zero (DBZ) is generated by an 8-input NAND, but that Z not always reflect what's (in the last cycle) on the internal data bus (DB part). After all, this would mean that (for example) in case of a JMP
instruction Z would be set according to the high byte of the address.
To avoid this the control logic enable flag setting for Z in a case by case situation via distinct control signals. Within the Hanson diagram they are mentioned as DBI/Z
in case of input operations (like LDA #
) and DBZ/Z
for arithmetic. In hardware it's an OR combination driven by several lines from the decoder PLA detecting certain opcode/sequence cases.
*2 - But beware Gift vs Gift :))
*3 - A rare case where a Wiki entry has at least some information to serve as pointer for details.
*4 - Like parity on a 8080 or zero detection for data by the 6800/6500 series.
*5 - By initial design that is, as 'grown' architectures like x86 have to squeeze them in.
*6 - Basically the same number of markers (avoiding the term Flag on purpose) gets used differently on different instructions. For example on a /370
- an arithmetic operation produced CC=0 for result zero, CC=1 for negative and CC=2 for positive and CC=3 for overflow
- A compare operation produces CC=0 for equal, CC=1 for less than and CC=2 for greater than
- a logic operation produces CC=0 for zero and CC=1 for non zero
- a bit test operation produces CC=0 for all-zero, CC=1 for mixed and CC=3 for all-one
- a move long produces CC=0 for all transferred, CC=1 for receive-is-too-short and CC=2 for receive-field-was-padded
- and so on...
As a result only two bits of condition code are needed to store such an abstract result - and only a single set of test instructions are necessary to act, no matter how different the instruction results are.