Page 1 of 1

How to correctly multiply or divide the values stored in registers?

Posted: Fri Nov 08, 2019 10:15 am
by MartaLabieniec
Hello Good People.

I have a problem with multiplying and dividing values stored in registers (registers for example: ebx, ecx.. etc. or xmm0, xmm1.. etc.)

I have a function in my game like this:

Code: Select all

add dword ptr [esi+04],-10
This function subtracts the value by 1 everytime when used - so, I have for example 46 potions, when I used one potion - this function is used and it is subtracting the value (46) by 1 so I have = 46 - 1 = 45 potions left.

I can manipulate this function to make this function adding 1 potion when used by changing function like this:

Code: Select all

add dword ptr [esi+04],10
If I want to add 5 potions at once, I must change the function like this:

Code: Select all

add dword ptr [esi+04],50
If I want to add 50 potions at once, I must change the function like this:

Code: Select all

add dword ptr [esi+04],320
So you can see by looking on these functions that all values are multiplying by 16.
When I want to add:
  • 1 potion - I must write 16 in Decimal or 10 in Hex
  • 2 potions - I must write 32 in Decimal or 20 in Hex
  • 50 potions - I must write 800 in Decimal or 320 in Hex
And my problem is with writing a correct script. I want to write a script with a GLOBAL ALLOC or other method to after activating the script, I will write the value corresponding to the number of potions that I want to get, and the script will itself multiply the value that I wrote by the number 16 <-- And with that I have a problem.. every time when I wrote a script, my game is crashing or I can't change the value xd. I was trying to write a multiply function using xmm registers but then if the multiply function is good, I don't know how to put xmm register into ebx or ecx or etc. register.

My examples of the scripts which I wrote:

1-st example using ebx, ecx registers and Global Alloc function:

Code: Select all

alloc(newmem,2048)
globalalloc(output,4)
label(returnhere)
label(originalcode)
label(exit)

newmem:

originalcode:
push ebx
push ecx
mov ebx,10
mov ecx,1
mul ecx
pop ebx
mov ecx,[output]
add dword ptr [esi+04],ecx
pop ecx
Game is crashing in this example and no matter what you enter in global alloc (output), it doesn't change the value in the game, it just frees it at a value which is already in game.
Also someone told me that : when using more than one register (like in this example: ebx, ecx) I must pop them in reverse order than I pushed them. Is it important? If yes why?

2-nd example using xmm registers:

Code: Select all

alloc(newmem,2048)
globalalloc(output,4)
globalalloc(multiplier,4)
label(returnhere)
label(originalcode)
label(exit)

newmem:

originalcode:
movss xmm0,[output]
movss xmm1,[multiplier]
mulss xmm0,xmm1
push ebx
mov(?)q xmm0,ebx ????? <---------- I don't know how to write it correctly to wrote multiplied value into ebx register
add dword ptr [esi+04],ebx
pop ebx
jmp exit
multiplier:
dd 10
In this example, I don't know how to correctly write the function which will move the multiplied value to the register - when I multiplied xmm0 with xmm1 the result will be stored in xmm0, am I right or not?

Yesterday and two days ago I was trying to fix it for several hours but I failed and got angry.. Can someone help me fix my script and explain me what I did wrong?

Thank you for your help.
Marta.

Re: How to correctly multiply or divide the values stored in registers?

Posted: Fri Nov 08, 2019 12:55 pm
by MartaLabieniec
Also I have second question:

In my game I have the situation like that: when i will wrote a 1 value in 4-byte, the value in game is changing to 1h 11min 35s = 4295s. I want to make a script that when I will write 1 it will be 1h = 3600s, not 4295s like is now.

So I calculated that I need to divide the 1 in 4-byte by 0.8381839348079162 in 4-byte but I don't know how to write in the script. Can you help me with that?

I am thinking about using xmm registers for that.

Re: How to correctly multiply or divide the values stored in registers?

Posted: Sun Nov 10, 2019 12:07 pm
by AlexS
MartaLabieniec wrote:
Fri Nov 08, 2019 10:15 am
and the script will itself multiply the value that I wrote by the number 16
(Google translation)

I have very poor English, but if I understand correctly, you need to multiply the number by 16. I think it is easier to do this:
shl eax,4
This instruction multiplies the contents of the eax register by 16.

Re: How to correctly multiply or divide the values stored in registers?

Posted: Sun Nov 10, 2019 12:22 pm
by AndChem
I think, it is boosters hack in Asphalt 8? the information i know, i can share.

Re: How to correctly multiply or divide the values stored in registers?

Posted: Sun Nov 10, 2019 12:28 pm
by AndChem
MartaLabieniec wrote:
Fri Nov 08, 2019 12:55 pm
Also I have second question:

In my game I have the situation like that: when i will wrote a 1 value in 4-byte, the value in game is changing to 1h 11min 35s = 4295s. I want to make a script that when I will write 1 it will be 1h = 3600s, not 4295s like is now.

So I calculated that I need to divide the 1 in 4-byte by 0.8381839348079162 in 4-byte but I don't know how to write in the script. Can you help me with that?

I am thinking about using xmm registers for that.
I am also trying this. I have tried it and found that minimum value of this function is 1h 11m 35s. I think you should find another value corrosponding to this....You need a function that divide this value...but actually value precision is hard. even a single digit may lead to change value upto 10000.

Re: How to correctly multiply or divide the values stored in registers?

Posted: Sun Nov 10, 2019 12:31 pm
by AndChem
can you describe your problem in detail?

Re: How to correctly multiply or divide the values stored in registers?

Posted: Thu Nov 21, 2019 6:28 pm
by TheByteSize
deleted

Re: How to correctly multiply or divide the values stored in registers?

Posted: Thu Nov 21, 2019 8:45 pm
by Csimbi
Marta,
why do you need floats for this?
You realize that 0x10 is 16, right?
0x10=16=2*2*2*2=2^4.
So, you can just shift the bits to the right (4 times), and use integer operand normally, then shift the bits back where the were.


mov eax,[esi+04]
shr eax,4
add eax,1 // Add 1 (or do whatever else you'd like to do here)
shl eax,4
mov dword ptr [esi+04],eax


Looking at your code.

Code: Select all

1-st example using ebx
1. You should look up the instructions manual and check what the MUL instruction actually does.
2. You pop the registers in the wrong order. You do understand how the stack works, right?
3. You don't use EBX for anything. Why slow down your PC?

Code: Select all

2-nd example using xmm registers:
I did not even read your code. Don't bother with XMM for this.
If you really can't resist the temptation, read up on the MOVD instruction - and maybe on CVTSI2SS and CVTSS2SI (or CVTSI2SD and CVTSD2SI if doubles tickle you fancy).