Page 1 of 1

How can assembler determine signed or unsigned?

Posted: Fri Apr 27, 2007 4:56 am
by sawerr
Hi
How can assembler determine that a number is signed or unsigned?
For example this code:

Code: Select all

mov ax, 9c17h
mov bx, 1209h
add ax, bx
i cannot do this:
mov ax, cc17h
It gives error.
But this works:
mov ax, 0xff17

But why? What is the problem? What is the problem with cc17h?
Also we are looking first bit of e number for oositive or negative.
+0 i.e. 0000 0000
-0 i.e. 1000 0000
But how can we understand if it is signed or unsigned?
Thanks.

Re: How can assembler determine signed or unsigned?

Posted: Fri Apr 27, 2007 5:22 am
by urxae
sawerr wrote:Hi
How can assembler determine that a number is signed or unsigned?
For example this code:

Code: Select all

mov ax, 9c17h
mov bx, 1209h
add ax, bx
i cannot do this:
mov ax, cc17h
It gives error.
But this works:
mov ax, 0xff17

But why? What is the problem? What is the problem with cc17h?
It looks too much like an identifier. Numbers should begin with a digit. Use 0cc17h or 0xcc17 instead.
Also we are looking first bit of e number for oositive or negative.
+0 i.e. 0000 0000
-0 i.e. 1000 0000
But how can we understand if it is signed or unsigned?
Thanks.
It doesn't quite work that way, at least on x86. It uses Two's complement to represent signed numbers. (This also means there's no such thing as -0 and +0, just 0)
This has the advantage that e.g. for addition and subtraction it doesn't matter if the numbers are signed or unsigned, since those operations are exactly the same at the bit level for unsigned integers and two's complement signed integers (of fixed widths)
For operations where it does matter whether the operands are signed or unsigned, separate instructions exist. (See MUL/IMUL, DIV/IDIV)

Posted: Fri Apr 27, 2007 5:36 am
by sawerr
Hmm thank you for explanation.
But i do not understand the last part of your answer.

Overflow flag is for signed number
Carry flag is for unsigned numbers.

I am using emu8086. An there is a number 8000h.
Is this signed or unsigned? Compiler must know it. Because if add a number to 8000h and if it overflow so is CF will be set or OF will be set?

You said:
"(...)it doesn't matter if the numbers are signed or unsigned"
But it think it matters.
Am i wrong?

Thanks again

Posted: Fri Apr 27, 2007 5:58 am
by Aali
the compiler must know because it has to know which flag to check
in assembly, you specify which flag you want to check

Posted: Fri Apr 27, 2007 6:41 am
by sawerr
http://www.piclist.com/techref/method/math/c-vs-o.htm
"carry is generally used for unsigned arithmetic and overflow is used for signed arithmetic."
For example 0111 + 1111 = 1 0110
So is this addition signed addition or unsigned addition. I asked this because of that.
Compiler sees 1111, its MSB is 1 but is this signed number or unsigned number?

Thanks

Posted: Fri Apr 27, 2007 7:09 am
by Solar
When you are doing Assembler, there's no syntactic difference between "signed" or "unsigned" integer. You just have a bit pattern.

If you do an operation, carry and / or overflow might be set. You give your values the semantic meaning of signed / unsigned by checking the one or the other.

(ASM coders: I am about 98% sure of this, but holler if I got it wrong.)

Posted: Sat Apr 28, 2007 7:28 am
by bontanu
In ASM it is very simple:

Code: Select all

test eax, eax
.IF SIGN?
 ; do operations here
.ELSE
 ; other operations here
.ENDIF
or

Code: Select all

cmp eax, 5
js @@is_signed ; test SIGN flag 
CPU has a lot of flags for such things. the most important are: Carry Flag, Zero Flag, Sign Flag, Overflow Flag.

And yes in reality there are only numbers, mostly unsigned ones for ALU without multiply/div. FPU does have a convention for negative zero and bit paterns that are "not a number".

Signed is a convention, a way to bias the number range in two partitions.

The most used or common convention is that the most significant bit represents the SIGNED / UNSIGNED status of the data and for the actual value it is a Two's complement.

The problem is in High Level Languages like C / C++ etc. They do not expose or have access to the Carry Flag. However they do have access to the signed flag hence the signed / unsigned casting and multiple problems with unsigned overflows that would have been detected by Carry flag.

Probably at the time high level languages have been designed most CPU's only had a Signed flag and no Carry or Overflow flag.

And probably by the time other much higher level languages have been designed their creators did not even know what a "flag" or a CPU is anymore ...

Posted: Tue May 01, 2007 5:23 am
by os64dev
i cannot do this:
mov ax, cc17h
It gives error.
But this works:
mov ax, 0xff17
Did your try mov ax, 0cc17h because hexidecimal numbers require a preceding zero.

oops mentioned before :oops:

Posted: Thu May 03, 2007 12:12 pm
by elderK
Signed Numbers are simply an interpretation of Binary.

Infact, a representation - twos compliment.

Observe...

0000 0000 to 0111 1111 (0 - 127)
1111 1110 to 1000 0000 (-1 to -127).

(That maybe wrong, but the point is simple).

Signed Numbers, are simply an interpretation of twos compliment.

Machines deal with Negative numbers, by using Twos compliment.
(Really, they deal with wrapping around the register / variable, in such a way that the subtraction actually takes place).

In eight bits...

0000 0000
'-------------------------- SIGN BIT. 0=positive. 1=negative.

If youd like a REAL explanation (complete with sensemaking stuff), Id suggest researching Microprocessor Arithmetic and Logic...

~zeii.

Posted: Thu May 03, 2007 1:26 pm
by mystran
zeii wrote: 0000 0000 to 0111 1111 (0 - 127)
1111 1110 to 1000 0000 (-1 to -127).

(That maybe wrong, but the point is simple).
Yup, you got it wrong:

1111 1111 to 1000 0000 = -1 to -128

Yeah, that's right -128 and 127 are the limits for 8-bit signed.

Posted: Thu May 03, 2007 2:13 pm
by Candy
Almost right. -128 .... -1 is 10000000 to 11111111.

So, if you add 1 and -1, 11111111 + 00000001 = (1)00000000 = 0.