mov eax,-5
why it is -5 and not 11111111111111111111111111111100 b <===Very huge number.
if i load -5 or 11111111111111111111111111111100 b how the program know what i wont to have in eax.
how can i make |-5| = 5 if i do not know that ^:eek:
There is no short answer but I give you some hints to
understand this your problem and many others simular to
this.
(In details I'm going to discuss it in "Position numeric system for lowlevel programmers")
Keep in mind that
1. Any numeric format exist not just a rules how to represent value in this
format but also by rules how this representation is used in math operations.
For example if you studied in scool how to divide or multiply numbers in
decimal numeric system using just pen and paper you learnt those algos
only for this system and can not apply them to make calculation with Romen
numeric system (format)
2. Doing math in computer you deal not only with value of operand, but
also in discretion of those values, in other words each operand has size
(particular number of digits (bits) it can have)
For better understanding the following info let's call it not "size" but
limits.
For example byte is limited by 0000 0000 to 1111 1111.
In any positioning numeric system base x (radix x)
number of digits can tell us
1. Number of values that can be represented in this number of digits
This number of values = redix in power of number of digits
for example in binary system radix = 2
number of digits in byte = 8
so that byte can have 2^8=256 different values (from 0 to 255)
2. Max value = (radix in power of number of digits)-1
in byte
2^8 - 1 = 255.
Example: in 3 bit operand
number of values = 2^3=8
max number = 2^3-1=7
Now important note to understand the whole thing of
negative number representaion in integers in computer:
What if number of digits in result of operation exceed the upper
limit?
Let's say we add to bytes and result we write in a byte also:
1111 1111
+
0000 0001
------------------
10000 0000
Result has 9 digits but operant of result limited to 8 digits.
So it will have only lower 8 digits and they represent 0, not 10000 0000b
Now we store this effect in our mind and go to next thing
important for our understanding:
If we have 7 bit operand the number of values in can represent = 2^7 = 128
If 8 bit operand number of values = 2^8 = 256.
Suppose we need to devide all values in 8 bit operand in two groups, each group having
the same number of values.
2^8=256/2 + 256/2 = 128 + 128 = 2^7+2^7 = 2 (2^7)
You can see that if we need to represent only one of the group
we need just 7 bits cause number of values in each group = 2^7
But we have 2 groups and we also have one extra bit.
It can have only 2 values 1 or 0. That means that number of
values of bit is equal to numbers of our groups.
Let us use this extra bit to destinct whether value
belongs to group 1 or group 2.
We use upper bit in 8 bit operand for this destinction.
So values from 0 000 0000 to 0 111 1111 belong to first group
And those from 1 000 0000 to 1 111 1111 belong to second group.
As you can see both groups freely use low 7 bits and have that for
the same number of values.
Now let's try to find a way to use first group (with upper bit = 0) as
positive numbers and second group (with upper bit = 1) as negative.
(0 this way is finding its place in positive numbers though it is
nor positive neither negative.)
Then we can call this upper bit (bit[7] in byte in zero based enumaration)
sign bit, and if this bit is =1 then we have negative number, if = 0 - positive.
But its not enough just to separate 256 possible values by some rules -
those rules must allow up to find some algos to do math operations
and have right results.
Now we close to end of this introduction, and possible understanding
of positive\negative int values representation in computers.
(So to called "complimentary 2 code")
Let's up recall two things
1. All 4 math operation can be represented as just one - addition
a+b=a+b
a-b =a+(-b)
a*b=a+a+a.. b times or b+b+b... a times
a/b=times of a-b untill reminder < b = times a+(-b) untill reminder < b
So if we can find way how find corresponence between representation of positive x in first
group and negative x in second group so that result of addition will produce right result
we can use the system.
2. x + (-x) =0
Now remember example when add 1111 1111 + 0000 0001 and get in used 8 bits
of result 0000 0000 ? Cause upper bit was out of size of our operand?
Then if corresponding to positive 0000 0001 we assign as -1 1111 1111 we've got
the right answer for x+(-x)=0 in bits that is used in 8 bits operands.
Let's check this "-1" about addition of other positive values:
-1+2=1
1111 1111 + 0000 0010 = 1 | 0000 0001 (in meaningfull low 8 bits = 0000 0001 = 1)
-1+5=4
1111 1111 + 0000 0101 = 1 | 0000 0100 (in meaningfull low 8 bits = 0000 0100 = 4)
So what binary number would be for -2? -120? etc.
We added to 0000 0001 number 1111 1111 and got 1 0000 0000.
So for any x from positive group (0000 0000 to 0111 1111) 0??? ????
as -x will serve binary number so that
0??? ???? + 1??? ???? = 1 0000 0000
For example positive 5 = 0000 0101
negative 5 = 1 0000 0000 - 0000 0101 = 11111011b
and low 8 bits in 1111 1011b+0000 0101 = 1| 0000 0000 = 0
So that we can have in byte 128 values from -1 to -128 with sign bit.
And 128 values from 0 to 127 with sign bit = 0
In byte we don't have corresponding positive value for -128 as
well there is no - 0 too.
As I said before in computers there is no such things as
add some value to othervalue
there are always add two values of SPECIFIED SIZE.
What if our operand is 16 bits or 32 or xx.. bits?
The rule of format is the same.
All values of with high bit =1 are negative and high (let us now call it "sign") bit = 0 are
positive.
And corresponding values are found the same way, the only difference
is that in 32bits operands sum of them equal lowest 33 bit value
in 16 bits = lowest 17bits value
For example in 32 bit -1 = 11111111 11111111 11111111 11111111b
in 16bits 11111111 1111111b
How comp knows size? :)
It is in opcode. Opcode always specifys size of operands in operations.
If you write push -5 it pushes dword FFFFFFFBh
if you write mov al,-5 it mov FBh in al 'cause al is 8 bits operand.
Now if we use the same operator for both sign and unsign values
how we ensure right result?
FFh can be treated as -1 sign and 255 unsign byte value?
That's is what CF,SF and OF flags for.
CF = 1 if bits in result is 1 more then operand size.
SF = 1 if highest (sign bit) in result is 1
OF treat SF as another carry flag and if CARRY FROM SF to CF <> to SF
it is set to 1.
If you need explonations why - I'll try to write examples to understand.
Anyway I will post materials about the issue to the board in more details
and you can wait untill it happens.
There are actually 3 very important things for lowlevel programming
that don't have good explonation in current asm books:
1. Operations in positioning numeric system in details
2. Understanding machine code specifics
3. Machine code algorithm in details.
Most questions I read on the board would have never been asked
if somewere it were explained in details with examples and exersizes.
It usually was different in old books, but instead of expanding the practice
in good old books contemporary books mostly look like reference of
recepies books and don't teach understanding of the very important basics.
I've decided to fill the gap, but I can not be sure for now that I'll be capable
to carry the task.