Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 01-19-2017, 07:51
chants chants is offline
VIP
 
Join Date: Jul 2016
Posts: 737
Rept. Given: 37
Rept. Rcvd 48 Times in 30 Posts
Thanks Given: 671
Thanks Rcvd at 1,064 Times in 482 Posts
chants Reputation: 48
Arithmetic coerce to negative one, and the like

See below, this was a simple late night mistake.

Just an interesting asm question, since we know that:

mul [val], -1

is inefficient in terms of clock cycles, is there a pure Boolean algebra (and/or/xor/not/neg) way of doing this without doing expensive multiplication?

Last edited by chants; 01-19-2017 at 08:48.
Reply With Quote
  #2  
Old 01-19-2017, 08:23
mcp mcp is offline
Friend
 
Join Date: Dec 2011
Posts: 73
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 7
Thanks Rcvd at 47 Times in 35 Posts
mcp Reputation: 12
You can move the value to a register and use NEG on it (assuming x86, 32 bit):
Code:
mov eax, [val]
neg eax
mov [val], eax
Alternatively, subtract from zero:
Code:
xor exc, ecx
mov eax, [val]
sub ecx, eax
mov [val], ecx
Reply With Quote
The Following User Says Thank You to mcp For This Useful Post:
chants (01-19-2017)
  #3  
Old 01-19-2017, 08:47
chants chants is offline
VIP
 
Join Date: Jul 2016
Posts: 737
Rept. Given: 37
Rept. Rcvd 48 Times in 30 Posts
Thanks Given: 671
Thanks Rcvd at 1,064 Times in 482 Posts
chants Reputation: 48
It is a bit early in the morning :-D

What I really meant to ask, was can we take an expression that is 0 or non-zero and convert it to 0 or -1. Either an all-0 or all-1 bitmask.

0->0
non-zero->-1

With pure arithmetic and no conditional statements. With conditional statements, there are many ways and all are easy. But without, its not as simple.

I noticed that (A OR -A) = 0 for 0, but turns the high bit on except for the sign bit power of 2 value e.g. 0x80000000. Perhaps using CDQ.

Code:
mov eax, [val]
mov edx, eax
neg edx
or eax, edx
cdq
mov eax, edx
Could that really be the simplest algorithm to do it?

The only other interesting property like this I could think of is <0 -> -1, 0 -> 0, >1 ->1 which also would be about as tricky without conditionals and purely arithmetically.

Actually you do something along the lines of multiply the output of previous code by the carry flag after subtracting from 0(sub, adc, mul) and I don't think you can avoid the mul.

Any thoughts
Reply With Quote
The Following User Says Thank You to chants For This Useful Post:
niculaita (02-08-2017)
  #4  
Old 01-19-2017, 09:05
atom0s's Avatar
atom0s atom0s is offline
Family
 
Join Date: Jan 2015
Location: 127.0.0.1
Posts: 397
Rept. Given: 26
Rept. Rcvd 126 Times in 63 Posts
Thanks Given: 54
Thanks Rcvd at 733 Times in 280 Posts
atom0s Reputation: 100-199 atom0s Reputation: 100-199
Using modern compiler optimizations it suggests that doing something like this:
Code:
    int32_t val1 = 1234;
    int32_t val2 = -val1;
Translates to:
Code:
mov     [ebp+var_4], 4D2h
mov     eax, [ebp+var_4]
neg     eax
mov     [ebp+var_4], eax
which is what mcp suggested in his first suggestion. If you write the code out as:
Code:
int32_t val1 = 1234;
val1 *= -1;
It also optimizes to the first suggestion.
Reply With Quote
  #5  
Old 01-19-2017, 09:46
mcp mcp is offline
Friend
 
Join Date: Dec 2011
Posts: 73
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 7
Thanks Rcvd at 47 Times in 35 Posts
mcp Reputation: 12
IIUC, you want to express something like this in assembly:

Code:
int result = n ? -1 : 0;
In that case, using neg+sbb does the trick:

Code:
mov eax, [val]
neg eax
sbb eax, eax
This works since neg sets the carry flag if its operand is non-zero, and clears it otherwise. The sbb instruction then subtracts the carry flag from zero and thus yields -1 for non-zero inputs, and zero otherwise.

Example:
eax contains a non-zero value, say x. neg eax turns this into -x and sets the CF. sbb eax, eax computes eax = eax - eax - cf <-> eax = 0 - CF.
Same drill when eax is zero initially.
Reply With Quote
The Following 2 Users Say Thank You to mcp For This Useful Post:
chants (01-19-2017), niculaita (02-08-2017)
  #6  
Old 01-19-2017, 16:55
chants chants is offline
VIP
 
Join Date: Jul 2016
Posts: 737
Rept. Given: 37
Rept. Rcvd 48 Times in 30 Posts
Thanks Given: 671
Thanks Rcvd at 1,064 Times in 482 Posts
chants Reputation: 48
Yes, that was the pearl of wisdom needed here. I had long forgotten this old SBB trick. From a C perspective its the casting to bool operation.

It would be nice if all the assembler bit tricks were compiled somewhere as similar to:
https://graphics.stanford.edu/~seander/bithacks.html
Reply With Quote
  #7  
Old 02-07-2017, 21:09
BlackWhite BlackWhite is offline
Friend
 
Join Date: Apr 2013
Posts: 80
Rept. Given: 4
Rept. Rcvd 14 Times in 6 Posts
Thanks Given: 12
Thanks Rcvd at 48 Times in 21 Posts
BlackWhite Reputation: 14
I think you may also take advantage of the instruction "setnz":
Code:
mov eax, [val]
or eax, eax
setnz al
neg al
movsx eax, al
Reply With Quote
The Following User Says Thank You to BlackWhite For This Useful Post:
niculaita (02-08-2017)
  #8  
Old 02-08-2017, 17:29
mcp mcp is offline
Friend
 
Join Date: Dec 2011
Posts: 73
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 7
Thanks Rcvd at 47 Times in 35 Posts
mcp Reputation: 12
@BlackWhite Why would you? It's more code and it's less efficient. Clearly, there is an infinite amount of additional ways to express this, but there is no advantage in doing so!?
Reply With Quote
  #9  
Old 02-08-2017, 23:23
BlackWhite BlackWhite is offline
Friend
 
Join Date: Apr 2013
Posts: 80
Rept. Given: 4
Rept. Rcvd 14 Times in 6 Posts
Thanks Given: 12
Thanks Rcvd at 48 Times in 21 Posts
BlackWhite Reputation: 14
Yes, setnz is not as efficient as sbb;
yet, it provides a variant way for the job.
Since sbb is forgotten by someone,
setnz & movsx may also be the case.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Hex-Rays and negative structure offsets jonwil General Discussion 3 02-20-2019 10:37


All times are GMT +8. The time now is 14:26.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( 1998 - 2024 )