would doing arithmetic operation on a pair of signed and unsigned numbers be legal?

后端 未结 5 1488
忘了有多久
忘了有多久 2021-01-03 02:23

I\'m more than half way through learning assembly and I\'m familiar with the concept of how signed and unsigned integers are presented in bits, I know that it might seem a w

5条回答
  •  走了就别回头了
    2021-01-03 02:48

    Mathematically, you do not add signed or unsigned number. There are only values modulo 232 (assuming that you have 32-bit registers). Such values cover a range of 232 consecutive integers, but you are free to interpret that range as beginning just about anywhere. "Signed" and "unsigned" are just two such interpretations.

    In other words, with 4-bit registers, the unsigned interpretation of "1011" is eleven, while the signed interpretation is minus-five. But there is only one value (which mathematicians usually call "eleven modulo 24" because mathematicians are traditionally fond of unsigned interpretation). For instance, if you add "0110" to that value (which is "six" in both signed and unsigned interpretations), then you get "0001", which is the proper value: minus-five plus six yield one, and eleven plus six is seventeen which is also equal to one when reduced modulo 24 (seventeen is one plus sixteen; "reducing modulo 24" is about dividing by sixteen [that's 24] and keeping the remainder only).

    Another way to say that is the following: the number of (binary) digits for a numerical value is conceptually infinite to the left. The CPU register only keeps the 32 rightmost bits. The unsigned interpretation is about assuming, conventionally, that all the leftmost bits are zero. The signed interpretation is about assuming, conventionally, that all the leftmost bits have the same value than the bit 31 (i.e. all are zero, or all are one). Either way, when you perform an addition (or a subtraction or a multiplication), carries propagate from right to left, not the other way round, so the values of those ignored bits have no bearing whatsoever on the 32-bit result. So there is only one "add" opcode, which does not care the slightest bit about whether its operands are, in the brain of the programmer, "signed" or "unsigned".

    Signedness must be taken into account when performing an operation which is not compatible with modulo arithmetics. Conversion into a sequence of decimal digits for display is such an operation. A more frequent case, however, is comparisons. Values modulo 232 are not ordered; they are in a kind of cyclic loop (when you add 1 to 232-1, and reduce modulo 232, you get back to 0). Comparisons make sense only when you consider integers in the whole range of integers. At that point, you must decide whether you use the signed or unsigned interpretation. Which is why x86 processors offer both jg (jump if greater, signed interpretation) and ja (jump if above, unsigned interpretation).

提交回复
热议问题