|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
++METHOS I post too much Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Fri Feb 06, 2015 6:08 pm Post subject: Negative Float Values |
|
|
Using the below code, jle west only works if the value is between -1.0 to 0.
Code: | cmp [analog_base],(float)1.0
jge east
cmp [analog_base],(float)-1.0
jle west |
If I change it to the below code, everything works as it should, however, jge west condition is also met when the value is between 0 to +0.99999999.
Code: | cmp [analog_base],(float)1.0
jge east
cmp [analog_base],(float)-1.0
jge west |
Am I doing something wrong? I've checked everything over several times. The target is 64bit, using CE 6.4.
Thanks.
|
|
Back to top |
|
|
Geri Moderator Reputation: 111
Joined: 05 Feb 2010 Posts: 5636
|
Posted: Fri Feb 06, 2015 6:39 pm Post subject: |
|
|
You have used cmp for float value. You should try float instructions instead.
http://www.jaist.ac.jp/iscenter-new/mpc/altix/altixdata/opt/intel/vtune/doc/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc89.htm
This is from the CE tutorial, step 4, float and double value compare (just to see how it looks like in a compiled software):
Code: | Tutorial-i386.exe+26128 - D9 05 C4F35500 - fld dword ptr [Tutorial-i386.exe+15F3C4]
Tutorial-i386.exe+2612E - D9 83 94040000 - fld dword ptr [ebx+00000494]
Tutorial-i386.exe+26134 - DED9 - fcompp
Tutorial-i386.exe+26136 - DFE0 - fnstsw ax
Tutorial-i386.exe+26138 - 9E - sahf
Tutorial-i386.exe+26139 - 72 3F - jb Tutorial-i386.exe+2617A
Tutorial-i386.exe+2613B - DD 05 C8F35500 - fld qword ptr [Tutorial-i386.exe+15F3C8]
Tutorial-i386.exe+26141 - DD 83 98040000 - fld qword ptr [ebx+00000498]
Tutorial-i386.exe+26147 - DED9 - fcompp
Tutorial-i386.exe+26149 - DFE0 - fnstsw ax
Tutorial-i386.exe+2614B - 9E - sahf
Tutorial-i386.exe+2614C - 72 2C - jb Tutorial-i386.exe+2617A |
_________________
|
|
Back to top |
|
|
SteveAndrew Master Cheater Reputation: 30
Joined: 02 Sep 2012 Posts: 323
|
Posted: Fri Feb 06, 2015 8:17 pm Post subject: Re: Negative Float Values |
|
|
++METHOS wrote: | Using the below code, jle west only works if the value is between -1.0 to 0.
Code: | cmp [analog_base],(float)1.0
jge east
cmp [analog_base],(float)-1.0
jle west |
If I change it to the below code, everything works as it should, however, jge west condition is also met when the value is between 0 to +0.99999999.
Code: | cmp [analog_base],(float)1.0
jge east
cmp [analog_base],(float)-1.0
jge west |
Am I doing something wrong? I've checked everything over several times. The target is 64bit, using CE 6.4.
Thanks. |
Yeah as Geri said a float value is compared differently than a standard byte value. You're comparing it as an integer value there...
This script depending on what you set defined "analog_base" to will follow a different path. It uses xmm register style "comiss"
(>= 1 will return 1 in eax)
(< 1 but >= -1 will return 0)
(< -1 will return -1)
Code: |
[enable]
alloc(ComparingFloats,1024)
label(analog_base)
label(onepointzero)
label(negativeone)
label(LessThanNegativeOne)
label(GreaterOrEqualToOne)
label(GreaterOrEqualToNegativeOneButLessThanOne)
registersymbol(ComparingFloats)
createthread(ComparingFloats)
ComparingFloats:
movss xmm0,[analog_base]
comiss xmm0,[onepointzero]
jae GreaterOrEqualToOne
comiss xmm0,[negativeone]
jae GreaterOrEqualToNegativeOneButLessThanOne
LessThanNegativeOne:
mov eax,-1
ret
GreaterOrEqualToOne:
mov eax,1
ret
GreaterOrEqualToNegativeOneButLessThanOne:
xor eax,eax
ret
//analog_base:
//dd (float)1.5
analog_base:
dd (float)-2
onepointzero:
dd (float)1
negativeone:
dd (float)-1
[disable]
dealloc(ComparingFloats)
unregistersymbol(ComparingFloats)
|
You can also do fcom/fcomp/fucom/fucomp etc...
Though it's a little more complex to branch after getting the results of the comparison but still simple enough...
Code: |
[enable]
alloc(ComparingFloats,1024)
label(analog_base)
label(onepointzero)
label(negativeone)
label(LessThanNegativeOne)
label(GreaterOrEqualToOne)
label(GreaterOrEqualToNegativeOneButLessThanOne)
registersymbol(ComparingFloats)
createthread(ComparingFloats)
ComparingFloats:
jmp ComparingFloats
fld [analog_base]
fcom [onepointzero]
fstsw ax
fwait
sahf
jae GreaterOrEqualToOne
fcom [negativeone]
fstsw ax
fwait
sahf
jae GreaterOrEqualToNegativeOneButLessThanOne
LessThanNegativeOne:
mov eax,-1
ret
GreaterOrEqualToOne:
mov eax,1
ret
GreaterOrEqualToNegativeOneButLessThanOne:
xor eax,eax
ret
analog_base:
dd (float)1.5
//analog_base:
//dd (float)0.5
//analog_base:
//dd (float)-2
onepointzero:
dd (float)1
negativeone:
dd (float)-1
[disable]
dealloc(ComparingFloats)
unregistersymbol(ComparingFloats)
|
_________________
|
|
Back to top |
|
|
++METHOS I post too much Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Fri Feb 06, 2015 8:46 pm Post subject: |
|
|
Thanks, Geri. I've never used these before.
The code below works as it should, however, the conditions are met even if I barely touch the analog stick. jge east performs even when the analog stick is only half-way. jle west performs even if I barely nudge the analog stick. Something is not right about this code. The values look kosher while viewing in float type, but I can see strange behavior when viewing as double or 8 byte. For some reason, I can not get the code to cooperate while working with float type...and that's the only type that seems to be displaying properly without any strange behavior. I must be doing something wrong still. I've calibrated my controller and even used different xinput1_3.dll.
Code: | fld qword ptr [analog_base]
fld qword ptr [floate]
fcompp
jge east
fld qword ptr [analog_base]
fld qword ptr [floatw]
fcompp
jle west
analog_base:
dq (float)0
floate:
dq (float)1
floatw:
dq (float)-1 |
EDIT:
Thanks, SteveAndrew. I just saw your post after I replied to Geri. I'll take a look at your post after I have my dinner.
EDIT2:
SteveAndrew, I'm having some trouble following your scripts. I used a variation of your first script with less success than my previous method (see below). There appears to be an infinite loop in your second script (or am I reading that right?). Sorry, my knowledge of assembly is very basic.
Code: | movss xmm0,[analog_base]
comiss xmm0,[floate]
jge east
movss xmm0,[analog_base]
comiss xmm0,[floatw]
jge west |
To clarify what I am trying to do...
[analog_base] holds the up/down value for the left analog stick on the gaming controller. The value is being loaded from a register from another injection point. I was using this label for something else and should have changed it, but I just forgot to. Anyway, when the L-Analog is pushed upwards, the value changes from (float) 0 to +1.0 (slightly higher than 1.0). Pushing downwards produces the opposite result (0 to -1.0, approximately).
I'm writing a fly mode script. I've never had this problem before...
Thanks, again.
|
|
Back to top |
|
|
SteveAndrew Master Cheater Reputation: 30
Joined: 02 Sep 2012 Posts: 323
|
Posted: Fri Feb 06, 2015 9:44 pm Post subject: |
|
|
Okay when using the fcom/fcomp/fcompp the flags aren't set automatically which you can use to branch.
After the float compare instruction you have to have:
Code: |
fnstsw ax //or fstsw ax
sahf
|
fstsw ax instruction puts the fpu "status word" into ax
sahf Transfers bits 0-7 of AH into the Flags Register. This includes AF, CF, PF, SF and ZF.
after that then you can do your ja/jb/je/ etc...
Also I ran into issues when using jge/jle for float comparisons with both methods... It appears you have to use the unsigned variety. Not sure why that is, but it only worked properly when I used jae/jb
EDIT: Yes my second one I forgot to remove that infinite loop... Since it creates a thread I was using that to debug it / test it... I would enable it then set a breakpoint after the jmp to self... then nop the jmp which would then hit my breakpoint.
So if you simple changed your conditionals it should start working properly:
Code: |
movss xmm0,[analog_base]
comiss xmm0,[floate]
jae east
movss xmm0,[analog_base]
comiss xmm0,[floatw]
jae west
|
or your first one add the fnstsw ax + sahf as well:
Code: |
fld qword ptr [analog_base]
fld qword ptr [floate]
fcompp
fnstsw ax
sahf
jae east
fld qword ptr [analog_base]
fld qword ptr [floatw]
fcompp
fnstsw ax
sahf
jbe west
|
_________________
|
|
Back to top |
|
|
++METHOS I post too much Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Fri Feb 06, 2015 10:23 pm Post subject: |
|
|
SteveAndrew wrote: | Okay when using the fcom/fcomp/fcompp the flags aren't set automatically which you can use to branch.
After the float compare instruction you have to have:
Code: |
fnstsw ax //or fstsw ax
sahf
|
fstsw ax instruction puts the fpu "status word" into ax
sahf Transfers bits 0-7 of AH into the Flags Register. This includes AF, CF, PF, SF and ZF.
after that then you can do your ja/jb/je/ etc... | -Yeah, I originally wrote it that way...the script works the same with or without the added fnstsw ax | sahf.
Quote: | Also I ran into issues when using jge/jle for float comparisons with both methods... It appears you have to use the unsigned variety. Not sure why that is, but it only worked properly when I used jae/jb | -This was the problem. Here is the working script (yay):
Code: | movss xmm0,[analog_base]
comiss xmm0,[floate]
ja east
movss xmm0,[analog_base]
comiss xmm0,[floatw]
jb west |
Thanks, guys. I'll +rep you both when I can.
|
|
Back to top |
|
|
SteveAndrew Master Cheater Reputation: 30
Joined: 02 Sep 2012 Posts: 323
|
Posted: Fri Feb 06, 2015 10:25 pm Post subject: |
|
|
Ahh see, so it was the conditionals! Well glad you got it working for you now!
_________________
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|