I get very confused when it seems like sometimes my code treats a certain value as signed and sometimes it treats it as unsigned when comparing values. How does the code know whether a value is signed or unsigned?
-
3If you're writing assembly code then it's your responsibility to know when to use which instructions. If you're programming in some other language it would be the responsibility of the compiler or interpreter, based on the data types you're using in your code. – Michael Oct 27 '16 at 05:35
-
Apart from instructions which are specifically signed or unsigned: it does not know. It is *you* who wrote the code who knows. For example, a comparison will set or clear various flags, not knowing whether your usage of that bit pattern is signed or unsigned. You use different versions of the branch instructions, which test different combinations of flags, according to your need. And if an instruction sets the sign flag from the result's m.s. bit, and your value is unsigned then you simply ignore it. – Weather Vane Oct 27 '16 at 06:48
-
Can you give me an example? – fuz Oct 27 '16 at 09:20
-
Frankly, it doesn't care. Signed vs unsigned is simply a representation and interpretation issue. – David Hoelzer Oct 27 '16 at 09:50
-
See [**Understanding Carry vs. Overflow conditions/flags for signed vs. unsigned**](http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt): you just test the appropriate flags after doing something. (The x86 flags for this look basically the same as MPS430 flags from the quick look I had at MPS430 from a previous question). – Peter Cordes Oct 27 '16 at 10:15
-
[A near-dup of this was asked just this week](http://stackoverflow.com/q/40182686/224132), but only got comments as answers (CPU doesn't care, use the right instructions to get the result you want). I also found this near-duplicate with good answers [about whether the C compiler or the CPU is responsible for handlign signed vs. unsigned](http://stackoverflow.com/questions/19464202/how-does-c-complier-handle-unsigned-and-signed-integer-why-the-assembly-code-fo). I closed the first question as a dup of the 2nd. With good answers here, this should prob. be a dup target of others, not closed. – Peter Cordes Oct 27 '16 at 10:35
3 Answers
Why do you think that assembly code has to "know" if a value is signed or unsigned?
For most operations the results of a signed and an usigned operation are the same:
signed int a = 5;
signed int b = -6; // 0xFFFFFFFA
signed int c;
c = a + b; // results in -1 which is 0xFFFFFFFF
And:
unsigned int a = 5;
unsigned int b = 0xFFFFFFFA;
unsigned int c;
c = a + b; // results in 0xFFFFFFFF
Some exceptions are division and comparison. Most CPUs have different assembler instructions for signed and unsigned operations in this case. The examples here are x86 assembler but msp430 should be similar:
signed int a, b;
if(a > b) { ... }
Results in:
mov eax, [a]
cmp eax, [b]
jle elsePart ; Note the "L" in "jle"
And:
unsigned int a, b;
if(a > b) { ... }
Results in:
mov eax, [a]
cmp eax, [b]
jbe elsePart ; Note the "B" in "jbe"

- 17,897
- 3
- 19
- 38
-
Great answer. And the main difference as well is that in a high level language such as Martin displayed (i.e. C, C++, C#) if you don't mark it signed/unsigned the compiler takes care of extra details which are what will make your computations seem incorrect. For example if you tried (0-1)=-1 but with unsigned integers you get FFFFFFFF as Martin mentions. Which is in fact -1. It's just that higher level languages are not showing you a -1 in that case b/c you told it you didn't want a "signed" number. Just some extra info that might help others. Wonderful answer though. – Kace36 Jul 20 '18 at 03:34
The machine doesn't care or know what is signed or unsigned unless you are telling it so.
At the level where assembler developers dwell, the machine is a brick and you are the conductor. You have to know enough to understand the contracts of the machine's instruction set and things like flags
to ensure a deterministic outcome.

- 7,758
- 4
- 35
- 45
Some processor instructions are signed, some others are not, if you declare a var in C, which is a unsigned, will compile into assembly with unsigned instructions (usually faster to execute) if you are using assembly, you will have to choose the instructions that you really need.

- 2,403
- 16
- 23
-
Most instructions (e.g. add/sub) don't care, and it's the same instruction for both. Maybe you're thinking of MIPS, where there's ADD vs. ADDU, with the difference being that ADD triggers an exception on overflow (or something like that, IIRC). Normally signed vs. unsigned only matters for right shift, division, and full-multiply (word * word -> double-word result). The low half of a multiply (i.e. up to the same width as the input operands) is the same regardless of signed or unsigned. (For 2's complement). – Peter Cordes Oct 27 '16 at 10:11
-
@rcgldr: I did point out all of those cases in my comment. I guess I meant most by instruction count in real programs, not most by fraction of the instruction set. But my main point was that many instructions aren't signed or unsigned, they're just instructions. **This answer seems to imply that you always need different instructions for signed vs. unsigned, even for addition, which is not the case.** – Peter Cordes Oct 27 '16 at 10:22
-
@PeterCordes - deleted my prior comment, it was meant for the other post, but you've covered it already. I'll delete this comment later. – rcgldr Oct 27 '16 at 14:40