Archived

This topic is now archived and is closed to further replies.

Khaos

Signed

Recommended Posts

In assembly language, there are no unsigned values, right? So how is it that there is in C++? Could someone explain how this works.. or why we need it? If C++ is translated into assembly language, how does it specify and unsigned number? Etc. Thanks.

Share this post


Link to post
Share on other sites
two's compliment ( or which ever it is) is sooooo cool that overflow takes care of the problem.

let's think 4 bit for a second.

unsigned 4-bit '5': 0101
signed 4-bit '-5': 1011 ((NOT 0101) + 1)
unsigned/signed 4-bit '0': 0000

0000 + 1011 = 1011 (0 + -5 = -5) (0 + 11 = 11)
0000 + 0101 = 0101 (0 + 5 = 5)
1011 + 0101 = (1)0000 (-5 + 5 = 0) (11 + 5 = 16 = overflow = 0)

*martix moves*

[edited by - C-Junkie on May 25, 2004 5:34:29 PM]

Share this post


Link to post
Share on other sites
There are 2 important unsigned operations:

unsigned
--------
imul - unsigned multiply
idiv - unsigned division


signed counterparts
--------
mul - signed multiply
div - signed division

This only applies to this operations, where sign truly matters, and as far as "and" and "sub" work, results are identical whether you wish the values are signed or unsigned (as c-junkie explained earlier)

Share this post


Link to post
Share on other sites
So how does that apply to C/assembly? How come C has signed and unsigned support, but assembly does not appear to be able to define an unsigned value. For instance: db makes a signed byte. There does not seem to be a way to make an unsigned byte. But in C there is a way. If C translates to assembly, how is a unsigned only variable specified? Also, how does the computer know a variable is signed or not. How does it know if a 4-bit word is 11 or 5, like you said. Does that have to do with the sign flag? When C translates to assembly, does it manipulate sign flags explicitly?

Do you think a modern language needs to have explicit support for both signed AND unsigned values? Or could it get away fine with only signed values, like Java apparently does?

Sorry for so many questions. Simply answer any ones you can. Thanks again.

Share this post


Link to post
Share on other sites
There are other cases, where the signed/unsigned matters: conversion -- when converting a smaller type to a larger one.
So, in a lot of cases there is no difference at assembly level (but then you usually you won't notice it in C, too). Where it matters, you have to distinguish, even at assembly level.
But it's good to ensure the use of correct types at compile time to prevent the coder from making stupid things.

[edited by - VolkerG on May 25, 2004 6:25:49 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Khaos
Also, how does the computer know a variable is signed or not. How does it know if a 4-bit word is 11 or 5, like you said. Does that have to do with the sign flag?
The computer does not know. Only the program knows. In C, when you declared a variable as unsigned, then the compiler will consistently treat it as an unsigned number, thus using the appropriate unsigned operations when necessary. If you wanted to treat it as a signed number temporarily, though, it would be as simple as using the signed operations. Nothing marks a number as signed or not. Only the program itself knows this information. If you give the computer a bunch of bits, and tell it to do signed multiplication, it will treat the bits as though they are signed. If you give it the same bits, but tell it to do an unsigned multiplication, then it will treat them as unsigned. It does whatever the program says.

Share this post


Link to post
Share on other sites
So what''s the point of unsigned variables if they really hold no meaning beyond the compiler?

If I said:


unsigned char x = 5 // or

signed char x = -5


Would they both compile to the same exact code? ex:

x db 00001001 ; binary, or
x db 5 ; decimal, or
x db -5 ; signed? I''m lost...

Sorry if I''m a bit confused. You are all helping very much though. I just want to know how to store values, signed or unsigned... and/or how a C compiler does it.

In assembly, is it impossible to specify a variable as unsigned? Or is it truly nothing, and sign (or unsign) is just an abstraction?

Share this post


Link to post
Share on other sites
Well MASM has SDWORD, SBYTE, SWORD for signed declarations. But they don't really make a big difference that I am aware of, besides identifying to you that you plan to treat them as signed.

The difference matters because, negative numbers use the high bit to say they are negative. So a signed byte that is negative will be 1??? ????, the question marks are just place holders. And, to understand signed numers on pc's, you need to understand that they are in two's compliment form.

SO let's say you have -5 in a byte. Of course the high bit is set because it's negative. But how do you do this? Easy, use the neg instruction. All it does is takes the 5 in binary 00000101. Inverts the bits -> 11111010, than adds 1. Now it becomes 11111011.

Now, you might have noticed that by using the high bit that you have lost the max number that can be stored in a byte. An unsigned byte can hold 0 - 255. A signed byte can hold -128 to +127 (because it only has seven bits to represent the number). But, as a result of using two's compliment, adding and subtracting follow the same rules for signed/unsigned numbers. And has been mentioned, the only real instructions that differ are multiplacation and division (idiv, imul), and the compare instructions also differ - because if the high bit is set it could either be a high number, or a negative depending on the context.

Anyway, if you treated a unsigned byte as a signed byte, the number could be converted wrong. For instance, let's say you have 254 in an unsigned byte (11111110). Now, you treat it as a signed byte, it's value would be -2. You just have to know what you want to do, and the kindof numbers your working with.

[edited by - pjcast on May 25, 2004 11:41:03 PM]

Share this post


Link to post
Share on other sites
db, dw, and dd do nothing except provide space to store data. db makes room for a byte-sized piece of data. Similarly, dw makes room for a word-sized piece of data. What the program actually stores in that space is up to you. Unlike typed languages, the computer doesn''t recognize the signed/unsignedness or format (floating-point/integral for instance) of a piece of data. All it sees is data.

It does however provide special instructions for manipulating data in different formats. There are comparison instructions for both signed and unsigned (icmp, cmp) as well as multiplication/division instructions for each. There''s probably more that I can''t think of ATM. In the same way, there are different instructions for handling floating-point versus integral data. All that differs between a signed byte and an unsigned byte is how the program chooses to handle them.

Share this post


Link to post
Share on other sites
I don''t think there is an icmp instruction. However, when I said that there was a signed version of compares, i really meant conditional jump instructions used after a cmp.

jg, jl, jge, gle (and a few more) are for signed numbers
ja, jb, jae, jbe (and a few more) are for unsigned numbers.

And of course, je, jz, jnz and jne work for both.

Share this post


Link to post
Share on other sites