Question

Intel 8085:

In my textbook it is said: "Carry Flag - this flag is the carry out from the MSB of the A-register. CY is set after an ADD instruction if carry out was generated from the A-register."

I get this, but how can be carry out generated from the MSB if the carry flag bit is located in the LSB of flag register-F?

I noticed that when I was learning about DAA (Decimal Adjust Accumulator).

enter image description here

Was it helpful?

Solution

It is just by definition that the carry output of the last ALU operation is captured to bit-0 of the flags. This kind of thing is relatively easy for hardware to accomplish in a number of ways. It could have just as easily been any (other) bit of the flags (or even somewhere else!).

From only the definition of the instruction set architecture, we don't really know where the flags carry bit is (physically) located or how it is implemented. In fact, we cannot say for sure whether the whole flags register is an actual 8-bit register just like all the others, or is instead an alias for a bunch of bits that are located around the ALU and/or in other places around the processor and unlike the more regular registers.

And the thing is that it doesn't matter to the programming model: the instruction set tells us how the carry bit is exposed or made accessible to the programmer, not how it is implemented. Further, a different implementation of the 8085 instruction set architecture may choose different internal implementation method.

So, as a programmer, you're dealing with an abstraction (an ISA) whose implementation details are complex and hidden, and as a chip designer, you're free to make variations of the underlying implementation (say, for performance) as long as you don't break the abstraction of the ISA (in this case, by ensuring that a read of the flags register always produces the last ALU carry as the LSB of the value returned by that read).


CY is set after an ADD instruction if carry out was generated from the A-register.

I find this wording awkward, as it suggests that the A register itself is the source of the carries; whereas I would say that is that it is the addition operation that generates carry. Again, from the instruction set architecture alone, we cannot know (and don't really need or want to as it turns out) whether the addition operation operands for ADD are shipped somewhere else on-chip to be summed and whose results are returned to the A register, or, whether the A register is indeed some true component of the ALU.


This (8085) processor was designed and documented in an era where the abstraction (the instruction set) and implementation were not as clearly separated as they generally are today. Today, for example, a processor may have multiple ALUs and choose to perform an addition operation on whichever is currently free. Today's processors have tended move away from the notion of a (single) primary A register associated directly with a (single) ALU, and this shows in both newer instruction set architectures (e.g. x64) as well as in underlying chip design & implementation.


in 8085; are there different instructions for unsigned, signed or mixed arithmetic operations (values)?

Not for the most part. As we noted in a previous question, add and subtract, carry-out, and with or without carry-in all work the same for unsigned and signed, so generally an instruction set won't provide separate instructions for signed vs. unsigned arithmetic.

(Unless it is providing instructions that automatically trap (throw exception) on overflow: then the processor will need to know if it should check signed or unsigned overflow, which means two different instructions for each of signed and unsigned).

However, for converting short values to longer values there will often be one capability for unsigned (sometimes called zero extension) and another for signed (sometimes called sign extension). Which is to say you want to convert either a unsigned byte into a signed or unsigned 16-bit value or a signed byte into a signed 16-bit value. Sometimes an instruction set will combine zero extension or sign extension with the load (from memory) instruction, so can have several kinds of byte load, for example.

The 8085 does not provide either zero extension or signed extension. However, some processors, like the 8085, can use two registers as a pair. So to convert an unsigned byte in the A register to a 16-bit unsigned value, we would move A into C and clear B, then use the B/C pair for the two byte value.

For sign extension of a signed byte in the A register, we would similarly move A to C, and then depending on a sign bit test for A, either clear B or set B to -1, with the signed 16-bit result in the B/C pair.

The compare instruction, CMP, on the 8085 provides for both unsigned compare and signed compare of bytes but the signed compare is undocumented and also not supported by the branch instructions!

To conditionally branch after a compare instruction, first decided if you want to interpret the two bytes as both signed or both unsigned.

For unsigned, we will test the carry bit for the value as documented by the CMP instruction. You would JNC or JC depending on how you wanted program flow altered and based on whether your testing for less than, or greater than.

For signed, you can use the undocumented K bit in the flags of the processor status word. However, there are no branch instructions for this bit so it is a bit of a process to extract the information. First, you push the whole 16-bit processor status word onto the stack, then pop it into the B/C register pair. Next move the C register, which holds a copy of the flags byte, into the A register, so we can now ANI "and immediate" with a byte value having a single bit set in the K register position and the rest clear. Finally we can now test the Z bit using JZ or JNZ conditonal branch instructions.

(If you had the relatively uncommon case of one signed byte and one unsigned byte, one technique would be to convert them both to 16-bit (or larger) signed values and compare using signed (16-bit) compare, which is how I'd approach this on a more capable processor; but on the 8085, all those operations are rather expensive, so I'd probably first test the unsigned byte for > 127, and if it was we'd know it is larger than the signed byte, and otherwise we can use the signed byte compare sequence.)

OTHER TIPS

The F-register is a special one which holds different flags. You can read and evaluate it. If you have an add-operation that overflows, it will set the carry bit in the F-register. A carry over is created if the MSB of either operand is set and the bitwise addition result is larger than the target. E.g. if you add the two unsigned bytes 0x80 and 0x81 the result would be 0x101. So the carry bit is set and the result holds just 0x01.

Licensed under: CC-BY-SA with attribution
scroll top