3

Everything discussed here will refer to Intel 8085 (8-bit architecture).

When using two's complement number "conversion" :

1.) If we take SBI 0F (subtraction) for example; immediate value 0F(hex) or 15 is subtracted from A register, which is loaded with 3C(hex) or 60. How will the microprocessor know whether e.g. 3C is equal to 60 (00111100) or -60 (11000100 --> invert+increment) which is actually 196 (which actually doesn't "fit" in 8-bit system)?

2.) Does the CPU or ALU consider the minus conversion when calculating equation like: -x-(-y)=z which transforms into -x+y=z ? If it does, how does it process the equation?

Lucenzo97
  • 293
  • 4
  • 11
  • The German Wikipedia explains the opcodes quite well: https://de.wikipedia.org/wiki/Intel_8085 The English doesn't, though :-/ –  Nov 29 '16 at 21:55
  • @ThomasKilian: There are plenty of suitable English references for the 8085 instruction set. – Robert Harvey Nov 29 '16 at 21:56
  • @RobertHarvey I'd guess so. It's more a hint to use google for finding the right opcode explanations. –  Nov 29 '16 at 21:58
  • https://en.wikipedia.org/wiki/Two's_complement explains how 2's complement works. –  Nov 29 '16 at 21:59
  • `3C` is `0011 1100`, period. `1100 0100` is `C4`. If you're paying close attention, you might have noticed that in both cases, the hex digit `C` matches up with the binary digits `1100`. That's not a coincidence. A hex digit corresponds to exactly four binary digits and always to the same four binary digits. – 8bittree Nov 30 '16 at 16:54

1 Answers1

4

First, the CPU just does what you tell it. Someone else has to translate an expression into CPU instructions.

Second, -x-(-y)=z and -x+y=z are equations (relation formulas), not assignment statements, at least in most languages I can imagine off hand. An expression like y-x is typically assigned to a variable looking something like var z = y-x;.

Third, what you're talking about, that -x-(-y) can be replaced by the much simpler y-x, is what we call optimization, and the CPU doesn't do that. Optimization comes as part of translation of the assignment or expression to the target CPU. Translation of expressions is rather large job in the general case. The translator has to concern with honoring the rules of the high-level language, while also accommodating the limitations of the underlying processor (for example, large expressions may require more temporary storage than available within the CPU, so memory must be employed). There is also no guaranteed best possible code sequence for the translation, and one translator may do better than another for any given expression.


Lastly, for operands of signed types, the processor will interpret operands whose high bit is set as negative, and those not set as positive, but, the fact is that for addition and subtraction, the processor doesn't actually care if the operands are positive or negative, because the logic to add or subtract positive vs. negative (even signed vs. unsigned) is the same. That is, for one, one of the advantages of 2's complement numeric representation of the integers.

If you issue an add instruction it will add regardless of the sign of the operands. The only time the sign is significant is if you want to interpret the overflow results or were doing a comparison. Then you have to know whether you were dealing with unsigned or signed numbers (but this doesn't require dynamic information as to positive vs. negative, instead we use static information as to signed vs. unsigned by the types of the operands). (Further, it only make sense to ask if a number is negative if the value is of a signed type as unsigned types hold values that are always non-negative).


You might be interested in studying compiler technology as it deals with these issues. The CPU is a complex piece of hardware, but even still, it gets a lot of support from operating systems, compilers, and standards like the various Application Binary Interfaces.


From: http://www.nhn.ou.edu/~baron/num_meths/Unsigned_and_Signed_Integers.pdf

There is an interesting consequence to the fact that in 2's complement arithmetic, one expects to throw away the final carry:

  • in unsigned arithmetic a carry out of the most significant digit means that there has been an (unsigned) overflow, but

  • in signed arithmetic an overflow is not so easy to detect. In fact, signed arithmetic overflows are detected by checking the consistency of the signs of the operands and the final answer. A signed overflow has occurred in an addition if:

    • the sum (addition) of two positive numbers is negative;
    • the sum (addition) of two negative numbers is positive;
  • and a signed overflow has occurred in in subtraction if:

    • subtracting a positive number from a negative one yields a positive result; or
    • subtracting a negative number from a positive one yields a negative result.

Wikipedia citation: "In a computer, the amount by which a calculated value is greater in magnitude than that which a given register or storage location can store or represent. Note that the overflow may be placed at another location."

Is this like well defined explanation of arithmetic overflow?

Yes (mostly -- If it was me, I'd omit the "calculated" word from that passage, see more on that further below).

Overflow happens whenever some value doesn't fit in the location it is targeted to be stored, but to be clear, you have to factor in the numeric representation, for example, as to whether signed or unsigned, and the size of target as compared with the size of the sources.

When you add or subtract two 8 bit values together you get a 9-bit answer, but usually, we're putting that 9-bit result back into an 8-bit register, and it is possible that that actual 9-bit value doesn't fit in 8-bits, and that's called an overflow situation. (Taking only the lower 8-order bits when there is overflow, results in a garbage value that might be vastly different in sign and magnitude than the original 9-bit value.)

As the Wikipedia article states, the overflow contents/value, which for add/sub, is just 1-bit, may go somewhere else, and, in many processors, that is the carry bit in the CPU flags status register.

This carry bit can be used in support of extended arithmetic, and for the 8085 this is what ADC is for. To add two 16-bit numbers, we use ADD on the two low order bytes, followed by ADC for the two high order bytes. One bit of overflow is, of course, still possible (e.g. the result is 17-bits), so in addition to the carry flag being read by ADC merely to propagate the carry from the low order, the carry flag is also written regarding the final result.

Now, the interpretation of overflow requires understanding the numeric type. For unsigned 8-bit arithmetic, if that 9th bit is clear, there is no overflow, otherwise there is overflow.

For signed arithmetic, the considerations for overflow are as stated above. Some processors will compute this directly for you, and, it looks like the 8085 does it but it is undocumented!

When doing multiplication of two 8-bit numbers the result is a 16-bit number, so, processors (or repetitive addition algorithms as you'd do on an 8085, which lacks a multiply operation) provide an 8 extra bits of result, e.g. by putting the high order result into a second 8-bit register. Now if your plan is to cut that answer back down to 8 bits, you can check overflow by inspecting the upper 8 bits of the 16 bit result. The interpretation issues for signed vs. unsigned remain, so unsigned overflow is avoided when the upper byte is zero, , and signed overflow is avoided if each bit of the upper byte matches the MSB of the lower byte.

Note that as Wikipedia states, overflow is mostly the result of attempting to place a calculated value n-bits in length into a storage location of n-1 or fewer bits. Note that there is no possibility of overflow for AND, OR, and, ROTATE operations, but there is for ADD, SUB, MULTIPLY, and SHIFT operations.

However, the article states that overflow is the result of calculation, and I'd point out that overflow can also happen without involving calculation just having been performed by the CPU/ALU. Non-arithmetic operations potentially causing overflow would be taking a 16-bit value and storing it in 8-bits. Also, taking an 8-bit unsigned value and storing it in 8-bits yet with the intention of treating it as a signed value later.


Ok, so by now you're probably wondering: with so much potential for overflow, how does anything work? And part of the answer lies in a consistency between memory addressing (e.g. pointer) size and the integer size. Many calculations (especially adds and subtracts) are used in locating values in memory (e.g. array indexing, struct field offsets). If the integer size and the memory addressing size are the same, then generally speaking, our programs will run out of memory before having overflow issues (it is important to check memory allocation results for the out-of-memory condition). (Computation that does not involve addressing and indexing needs to be checked carefully for potential overflow, sometimes by limiting input ranges, sometimes after the fact by stopping the program, and sometimes by capping values to max or min as is common in graphics.)

Erik Eidt
  • 33,282
  • 5
  • 57
  • 91
  • Note that the OP is a beginner to Assembly Language in general and 8085 architecture specifically (he's asked several similar questions prior to this). It's likely that his question arises from a simple misunderstanding of the nature of two's complement, as implemented on the 8085. – Robert Harvey Nov 29 '16 at 23:11
  • @RobertHarvey, yes, I've been watching their questions. Some are very specific to the 8085, but today, I think popping up to a higher level and talking just a bit about how languages use instruction sets may be where the answer is: CPU's don't process high level language equations, that is, until they have been translated to machine code, eh? – Erik Eidt Nov 29 '16 at 23:13
  • @ErikEidt : But what in microprocessor, like 8085, considers that sign (the most significant bit or the number)? I mean, what/who determines whether the MSB should be considered as a sign or as an another bit added to the whole value? – Lucenzo97 Nov 30 '16 at 13:26
  • @RobertHarvey : I just want to make things clear, so in the future, when I will actually start with programming, there will be as few problems as possible. Especially because I am studying assembly and other stuff with connection to this (architecture, instruction set, I/O devices, memory, etc.) on my own. – Lucenzo97 Nov 30 '16 at 13:31
  • 1
    @LuKa: The Arithmetic Logic Unit (ALU) is probably what is responsible for making that determination. – Robert Harvey Nov 30 '16 at 15:23
  • 2
    @LuKa, for 2's complement *addition & subtraction*, it doesn't matter whether the MSB is treated a sign bit or just another digit as the CPU uses ***the exact same logic regardless of signed/unsigned type interpretation and for signed types, regardless of positive/negative values***. This is the beauty of 2's complement representation. What matters is later when/if you look at the flags after an addition/subtraction. You, the programmer, gets to decide how to interpret the flags: one way if you want to know, say, signed overflow, and another way if you want to know unsigned overflow. – Erik Eidt Nov 30 '16 at 16:05
  • 1
    @LuKa, here are some interesting articles you may find of value regarding the interpretation of the flags for signed vs. unsigned types, and 2's complement addition: http://www.righto.com/2013/02/looking-at-silicon-to-understanding.html, and, http://www.righto.com/2012/12/the-6502-overflow-flag-explained.html. I have also added some text to my answer regarding interpretation of overflow. – Erik Eidt Nov 30 '16 at 16:06
  • @ErikEidt : Things are getting clearer every second of reading you answer and comments. Only one more thing is I am not sure about, and that is an overflow (arithmetic overflow). Wikipedia citated: "In a computer, the amount by which a calculated value is greater in magnitude than that which a given register or storage location can store or represent. Note that the overflow may be placed at another location." – Lucenzo97 Nov 30 '16 at 18:26
  • Is this like well defined explanation of arithmetic overflow? – Lucenzo97 Nov 30 '16 at 18:27
  • @LuKa, See edit appended to my answer. – Erik Eidt Nov 30 '16 at 19:13
  • 1
    @LuKa, I added another side note on overflow. – Erik Eidt Nov 30 '16 at 19:24
  • @ErikEidt I don't know how to thank you for finding literature instead of me :D – Lucenzo97 Nov 30 '16 at 20:38