flat assembler
Message board for the users of flat assembler.

 Index > Main > Long signed multiplication
Author
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 17 Mar 2010, 02:53
(I fill disappointed people even before writing this very elementary question...)

I've been searching for a while but can't find a more direct method. Is not possible to perform the multiplication without taking the absolute value of both operands first? I'm trying to do 64x64 to get 128-bit answer, but the code and description I've seen so far takes the absolute value of the operands and then performs negation of the 128 result when the sign of the operands were different.

This also has to be done this way in the case I promote both operands to 128-bit signed values first? (And I do 128x128 to get 128 answer this time)*

If someone has a good reference of how imul works internally I would like it as it seems I need to refresh my memory with some basic concepts...

* Almost convinced it is not required, but I don't know anymore...

PS: Note that "(i)mul r64/m64" is not an option, "(i)mul r32/mem32" at most.
17 Mar 2010, 02:53
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 8035
Location: Kraków, Poland
Tomasz Grysztar 17 Mar 2010, 06:11
You may find some notes about it here.
17 Mar 2010, 06:11
edemko

Joined: 18 Jul 2009
Posts: 549
edemko 17 Mar 2010, 08:16
LocoDelAssembly
I'm trying to do 64x64 to get 128-bit answer, but the code and description I've seen so far takes the absolute value of the operands and then performs negation of the 128 result when the sign of the operands were different.
Code:
```Use sign xorring:
0 xor 0 = 0 ; '+' * '+' = '+'
1 xor 1 = 0 ; '-' * '-' = '+'
0 xor 1 = 1 ; '+' * '-' = '-'
1 xor 0 = 1 ; '-' * '+' = '-'
```

My question: "xoring" or "xorring"?
17 Mar 2010, 08:16
revolution
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 18942
revolution 17 Mar 2010, 08:27
Without sign detection (i.e. ignore the sign bits) you can get the lower half of the result without any extra code. It is only the high half that creates the difference.

64x64 ---> 64 means you don't have to care about the sign bits.
128x128 ---> 128 means you don't have to care about the sign bits.
64x64 ---> 128 means you do have to consider the sign bits.

There really is no other way.
17 Mar 2010, 08:27
edemko

Joined: 18 Jul 2009
Posts: 549
edemko 17 Mar 2010, 08:46
revolution
Without sign detection (i.e. ignore the sign bits) you can get the lower half of the result without any extra code. It is only the high half that creates the difference.

-1, what will you say?

revolution
64x64 ---> 64
128x128 ---> 128
64x64 ---> 128

64 bit signed * 64 bit signed = as maximum (2^64)-1 * (2^64)-1 = (2^128)-(2^64-1) ~ 2^128 i.e. ---> 128
revolution once told this and now is negating himself It may happen i did not understand that "64x64 ---> 64" etc.
17 Mar 2010, 08:46
edemko

Joined: 18 Jul 2009
Posts: 549
edemko 17 Mar 2010, 08:48
128 means log(2;64 signed * 64 signed)
17 Mar 2010, 08:48
revolution
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 18942
revolution 17 Mar 2010, 08:55
serfasm wrote:
-1, what will you say?

revolution
64x64 ---> 64
128x128 ---> 128
64x64 ---> 128

64 bit signed * 64 bit signed = as maximum (2^64)-1 * (2^64)-1 = (2^128)-(2^64-1) ~ 2^128 i.e. ---> 128
revolution once told this and now is negating himself It may happen i did not understand that "64x64 ---> 64" etc.
No problem.

-1 * -1 = 1
(2^64-1) * (2^64-1) = (0xff...fe00..01) or 0x00...01 when just taking the lower 64 bits.
17 Mar 2010, 08:55
edemko

Joined: 18 Jul 2009
Posts: 549
edemko 17 Mar 2010, 10:04
i wrote
64 bit signed * 64 bit signed = as maximum (2^64)-1 * (2^64)-1 = (2^128)-(2^64-1) ~ 2^128 i.e. ---> 128
wrong minuend -1 used, -2 must be
17 Mar 2010, 10:04
edemko

Joined: 18 Jul 2009
Posts: 549
edemko 17 Mar 2010, 10:23
LocoDelAssembly, do you prefer general purpose registers only?
17 Mar 2010, 10:23
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 17 Mar 2010, 15:55
Got it, thanks guys.
17 Mar 2010, 15:55
edemko

Joined: 18 Jul 2009
Posts: 549
edemko 18 Mar 2010, 06:39
LocoDelAssembly, i was a bit wrong with the ranges.
Maximum one we may get is (maximum negative)^2 i.e. there will be positive: -2^63 * -2^63 = 2^126 =
= 0100..0b = \$4..0.
As you can see, multiplying 64*64, 128bit got.
At my oppinion |64| * |64| is the easiest.
If you fill difficult with those lo-o-ngish numbers imagine xxxxb is a dword then xxxx'xxxxb will be a qword. Hence 1000'0000b is max.neg and 0111'1111b is max.pos. Tomasz calls this extrapolation(and he is right).
Well, max.pos*max.pos < max.neg.*max.neg = (2^63-1)^2 <- extrapolation. Remembering that (a+b)^2 = (a+b)(a+b) = aa+ab+ba+bb = a^2+2ab+b^2 we get (2^63)^2 + 2*2^63*(-1) + (-1)^2 = 2^126 - 2^1*2^63 + 1 = 2^126 - 2^64 + 1 = 2^126-1 - 2^64-1 + 3.

Currently i'm not at my own pc and text formating may be inconvinient, sorry.
18 Mar 2010, 06:39
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum