• Advertisement
Sign in to follow this  

Negate a number in assembly

This topic is 4323 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'd like to know how to negate a number in assembly: a = -a; //a is a 32bit integer I tried mov exa,a; and eax,0xFFFFFFFF; mov a,eax; but this always changes the sign to negative. if a is already a negative number then the result should be positive. I searched the net but can't find anything on that. Please help. Thanks!

Share this post


Link to post
Share on other sites
Advertisement
xor eax, 0x80000000;

Edit: nm, it's dependant on representation of number.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
xor eax, 0x80000000;


this won't work for two's complement representation (used on x86).

Share this post


Link to post
Share on other sites
Quote:
Original post by echohead
Quote:
Original post by Antheus
xor eax, 0x80000000;


this won't work for two's complement representation (used on x86).


Yes, it occured to me right after posting.

Share this post


Link to post
Share on other sites
Quote:
Original post by JoeZ
and eax,0xFFFFFFFF;

but this always changes the sign to negative.

That's impossible. and eax, 0xffffffff does not change the value at all.

Share this post


Link to post
Share on other sites
xor would work as well. BTW Have you looked into Intel's manuals?

Share this post


Link to post
Share on other sites
I am not familiar with x86, but in MIPS you could just do something like:

add $1,$0,-$1

Or you could do a bitwise negation and add 1 for twos-complement numbers.

Share this post


Link to post
Share on other sites
Quote:
Original post by Raghar
xor would work as well. BTW Have you looked into Intel's manuals?


intel manuals (they're 100% free when available)

Quote:

Printed copies of the IA-32 Intel® Architecture Software Developer's Manuals, Volumes 1-3 are not available at this time. Please check back in early May to order the manuals.

Share this post


Link to post
Share on other sites
Quote:
Original post by Raghar
xor would work as well.


No, it wouldn't. The answer is to use the "neg" instruction. That's why it's there.

Share this post


Link to post
Share on other sites
not eax
add eax, 1


sub eax (0), a

I talked about alternatives, not about what is optimal.

Share this post


Link to post
Share on other sites
Quote:
Original post by bakery2k1

neg eax


Quoted for emphasis.

Share this post


Link to post
Share on other sites
Quote:
Original post by gumpy macdrunken
intel manuals (they're 100% free when available)

Quote:

Printed copies of the IA-32 Intel® Architecture Software Developer's Manuals, Volumes 1-3 are not available at this time. Please check back in early May to order the manuals.


Well he could download them for now.

Share this post


Link to post
Share on other sites
Is this turning into a joke thread?

Just in case, there is an instruction that does exactly what the OP wants and there is no reason not to use it.

Quote:
Original post by bakery2k1
neg eax

Share this post


Link to post
Share on other sites
You could also use:


xor ebx, ebx
sub ebx, eax // result is now in ebx


another alternative:


xor eax, -1
sub eax, -1


:-)

Share this post


Link to post
Share on other sites
Quote:
Original post by dustamulet
Hmmm....I'm pretty sure the only way to negate a number in assembly is to use xor somehow........


Yeah, the negate (neg) instruction won't work. </sarcasm> Why do people even discuss alternatives when we have the neg instruction?

Share this post


Link to post
Share on other sites
Quote:
Original post by dustamulet
Hmmm....I'm pretty sure the only way to negate a number in assembly is to use xor somehow........


Quote:
Original documentation by Intel
NEG-Two's Complement Negation

Opcode Instruction 64-Bit Mode Compat/Leg Mode Description
F6 /3 NEG r/m8 Valid Valid Two's complement negate r/m8.
REX + F6 /3 NEG r/m8* Valid N.E. Two's complement negate r/m8.
F7 /3 NEG r/m16 Valid Valid Two's complement negate r/m16.
F7 /3 NEG r/m32 Valid Valid Two's complement negate r/m32.
REX.W + F7 /3 NEG r/m64 Valid N.E. Two's complement negate r/m64.

Description
Replaces the value of operand (the destination operand) with its two's complement. (This operation is equivalent to subtracting the operand from 0.) The destination operand is located in a general-purpose register or a memory location.

Share this post


Link to post
Share on other sites
Quote:
Original post by dustamulet
Hmmm....I'm pretty sure the only way to negate a number in assembly is to use xor somehow........

No, there's several ways. However the best solution is to use NEG.

But you can also:
a) subtract from zero
b) invert all the bits and then add one
c) sub one and then invert all the bits
d) use a LUT :-)
e) whatever you can think of that achieves the same as NEG

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
A little report

int main()
{
int a = 12, b = 12, c = 12, d = 12;
cout << "a = " << a << "\t-a = " << -a << "\n";
cout << "b = " << b << "\tneg b = ";
__asm neg b
cout << b << "\n";
cout << "c = " << c << "\t-1*c = " << -1 * c << "\n";
cout << "d = " << d << "\t 0-d = " << 0 - d << "\n";
}

//Output:
a = 12 -a = -12
b = 12 neg b = -12
c = 12 -1*c = -12
d = 12 0-d = -12



Share this post


Link to post
Share on other sites
Guest Anonymous Poster
No register is needed for the NEG instrucion.

Quote:

Printed copies of the IA-32 Intel® Architecture Software Developer's Manuals, Volumes 1-3 are not available at this time. Please check back in early May to order the manuals.

That's too funny. I just wonder how many of those were ordered by Gamedevvers.

Share this post


Link to post
Share on other sites
Hehe, I ordered them... Then I wasn't around when they tried to deliver them, so they got sent back after a few days... [lol]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement