Click here to Skip to main content
15,867,330 members
Please Sign up or sign in to vote.
4.56/5 (4 votes)
See more:
This is First Code ::
ASM
     unsigned int F1 = 2147483647;
01092C0E  mov         dword ptr [F1],7FFFFFFFh
     unsigned int F2 = 2147483647;
01092C15  mov         dword ptr [F2],7FFFFFFFh

     unsigned int F3=F1+F2;
01092C1C  mov         eax,dword ptr [F1]
01092C1F  add         eax,dword ptr [F2]
01092C22  mov         dword ptr [F3],eax

the result is : 4294967294

This is Second Code ::

ASM
     int F1 = 2147483647;
010A6ECE  mov         dword ptr [F1],7FFFFFFFh
     int F2 = 2147483647;
010A6ED5  mov         dword ptr [F2],7FFFFFFFh

     int F3=F1+F2;
010A6EDC  mov         eax,dword ptr [F1]
010A6EDF  add         eax,dword ptr [F2]
010A6EE2  mov         dword ptr [F3],eax


the result is : -2



How assembly Know if this is Signed or Unsigned number ??
Posted

I'm afraid the Solution 1 and Solution 2, correct in principle, did not uncovered the essence of things. Here is the trick: the binary representation of integer numbers is specially designed the way ignoring the difference between unsigned numbers. This representation is dominated in almost all modern systems and is called "2's complement". Here is how it works: http://en.wikipedia.org/wiki/2%27s_complement[^].

Here is the idea: let's say, you have the binary representation of byte (integer number of any size, actually, this is only an example) of 11111111. It represents unsigned 255=0xFF or signed −1. Different mathematical values, right? Let's add some other byte to is, say, (same mathematical value for both signed and unsigned). Let's add them formally, using school "column" method and carrying over to left the bit in case of overflow:
C#
 11111111
+
 00000011 = 3
=========
 00000010 = 2
In both signed and unsigned representation, we have the same result (in case of unsigned, we also have "wrap around" effect: adding 1 "increment" maximum value of 255 to 0, and adding 2 makes the result equals to 2).

In some other cases, we get different mathematical values but the same binary result. For example:
C#
 11110110
+
 00000010 = 2
=========
 11111000

In signed values, it means −10 + 2 = −8, in unsigned: 0xF6 + 2 = 0xF8, or 246 + 2 = 248.

You can check up and see that the same takes place in all other integer arithmetic operations. As you can see, the CPU does not care about signed and unsigned representations; all calculations are the same, only the interpretation of the results are different. You can also check up that you can mix signed and unsigned values in the same expression, but need to take care about not crossing the barriers of the maximum and minimum values, which are of course different.

Also, you should understand that the absolute values of signed negative value is not the same as the signed value with flipped sign bit. If you have −1, flipping the sign bit won't give you 1, it will be 127. It has important implication: there is no binary two representations for zero, −0 and +0 has the same representation.

—SA
 
Share this answer
 
v4
Comments
Anderso0on 7-Dec-13 20:46pm    
so :
how is related to determination this binary number is signed or unsigned ?? compiler !!
Sergey Alexandrovich Kryukov 7-Dec-13 20:54pm    
I don't quite understand the meaning of this your comment, and am not sure that you understand mine.

This is not directly related to the compiler. Just think about it. Of course, the compiler "knows" the types, but only to generate errors or warning when you misuse the types uses together; also, it is used to present the data as string, so the user could see the expected mathematical value. The result of compilation at the level of compilation results in the code agnostic to the signer/unsigned choice. This is important to understand.

Anyway, any questions? Will you accept the answer formally?

—SA
pasztorpisti 8-Dec-13 5:55am    
+5. This is the correct explanation but it will need some extra effort and bit twiddling from OP's side to understand for sure. It reminds me of explaining text encoding. A lot of experienced coders get confused that the text itself is just a binary blob and encoding matters only when you try to interpret it somehow (for example by iterating over the unciode codepoint sequence it describes in the text renderer).
Sergey Alexandrovich Kryukov 8-Dec-13 12:22pm    
Thank you very much. This is the whole point: "some extra effort and bit twiddling from OP" is the most effective way to understand something.

From time to time, I face with developers who fail spectacularly over integer presentation. If does dot matter during calculation, but reveals when the bits control some hardware.

—SA
An unsigned variable indeed represents positive values including 0.
The signed data type is used for values that can hold both positive and negative numbers. Say for example if you wish to represent your bank account information, it is useful to be represented as a signed number. Unsigned numbers are usually used as array indices which can't hold negative values.

"For the computer however it makes no difference if you use signed or unsigned version of the data type, regarding the memory space or performance."
 
Share this answer
 
The assembly doesn't 'know' anything. The compiler generates the appropriate code for operations on signed or unsigned data. In the code you've shown, there is no need to do anything different for each case, and so you see the same dissasembly. Whether When the number is displayed its simply interpreted differently.

One example of code that will produce different code is using the bit-shift operator >> (shift right)

Code:
C++
int main()
{
    int i = -2;
    unsigned int j = -2;

    i = i>>1;
    j = j>>1;

    printf("int i = %d\n", i);
    printf("unsigned int j = %u\n", j);

    return 0;
}


Output:
int i = -1
unsigned int j = 2147483647



Disassembly:
CPU Disasm
Hex dump       Command                                                Comments
C74424 1C FEF MOV DWORD PTR SS:[LOCAL.1],-2
C74424 18 FEF MOV DWORD PTR SS:[LOCAL.2],-2

-----------------------------------------------------------------------
D17C24 1C     SAR DWORD PTR SS:[LOCAL.1],1
D16C24 18     SHR DWORD PTR SS:[LOCAL.2],1
-----------------------------------------------------------------------

8B4424 1C     MOV EAX,DWORD PTR SS:[LOCAL.1]
894424 04     MOV DWORD PTR SS:[LOCAL.7],EAX                       ;<%d> => -2.
C70424 643040 MOV DWORD PTR SS:[LOCAL.8],OFFSET 00403064           ;fmt = "int i = %d
"
E8 60080000   CALL <JMP.&msvcrt.printf>                            ;MSVCRT.printf
8B4424 18     MOV EAX,DWORD PTR SS:[LOCAL.2]
894424 04     MOV DWORD PTR SS:[LOCAL.7],EAX                       ;<%u> => 4294967294.
C70424 703040 MOV DWORD PTR SS:[LOCAL.8],OFFSET 00403070           ;fmt = "unsigned int j = %u
"
E8 4C080000   CALL <JMP.&msvcrt.printf>                            ;MSVCRT.printf
B8 00000000   MOV EAX,0
C9            LEAVE
C3            RETN



In the case of an unsigned int, shifting right just means that we (a) remove the LSB, (b) shift all of the remaining bits 1 position to the right and then (c) fill the MSB with a 0.

However, in the case of a signed int the required behaviour is different. Steps (a) and (b) remain the same, but step (c) may have a 1 or a 0 inserted - this depends on whether or not the number is negative. A negative number will have a 1 inserted, a positive one will have a 0 inserted.

The instruction for an unsigned int is SHR (Shift Right), while the instruction for a signed int is SAR (Sign Adjust (shift)Right).
 
Share this answer
 
v5
Comments
Sergey Alexandrovich Kryukov 7-Dec-13 16:45pm    
I voted 4. You just made some correct statements but did not really explain the essence of things: the nature of integer representation called "2's complement". Add added my answer to complement yours with this. Please see.
—SA
enhzflep 7-Dec-13 16:52pm    
Thanks. :)
Snap! I entirely overlooked the fact that an explanation of 2's complement system would make for a complete solution - providing the 'why', not merely the 'what'. I can't vote your solution 6, so I'm afraid you'll need to be content with a +5 from me. :grin: (great point re: bit-flipping made in the last paragraph, too - thorough, as always)
Sergey Alexandrovich Kryukov 7-Dec-13 18:11pm    
Absolutely. Thank you so much.
—SA
Assembly does not know if number are signed or not. The difference is how the data is interperted and which instructions are used (when it does matters).

If you try something a bit more complex like multiplication, bit shift (to the right), or work on 64 biut number on a 32 processor, you will see that different instructions are used in some case.

The compiler know which instruction to use depending on the data type.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 7-Dec-13 16:44pm    
I voted 4. You just made some correct statements but did not really explain the essence of things: the nature of integer representation called "2's complement". Add added my answer to complement yours with this.
—SA
Signed variables, such as signed integers will allow you to represent numbers both in the positive and negative ranges.

Unsigned variables, such as unsigned integers, will only allow you to represent numbers in the positive.

Unsigned and signed variables of the same type (such as int and byte) both have the same range (range of 65,536 and 256 numbers, respectively), but unsigned can represent a larger magnitude number than the corresponding signed variable.

For example, an unsigned byte can represent values from 0 to 255, while signed byte can represent -128 to 127.

Wikipedia page on Signed number representations explains the difference in the representation at the bit level, and the Integer (computer science) page provides a table of ranges for each signed/unsigned integer type.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900