Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Assembler: How Can I Divide Directly From r8d Register?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Gear2ndGandalf
Newbie cheater
Reputation: 0

Joined: 22 Jan 2018
Posts: 19
Location: USA

PostPosted: Tue Feb 06, 2024 9:10 pm    Post subject: Assembler: How Can I Divide Directly From r8d Register? Reply with quote

This address executes when an enemy hits player, and the damage output varies by enemy type and action. Instead of mov r8d,#1, where all enemies do 1 damage to the player, I want to divide the general damgae done by 2 as to keep in line with the variable damage output from a variety of enemies and attacks.

Google searched up and down just to find examples regarding eax, ah, bl, ebx, ax, bx. Though I fail to implement the code properly and keep crashing the game as an enemy attack lands.

Please view photo for code.
Code:
push eax
push ebx
mov ebx,2
movsx r8d,word ptr [r10+000019A2]
div ebx
mov r8d,eax
pop ebx
pop eax

Clearly what I'm doing doesn't make sense.



Sample Code.PNG
 Description:
movsx r8d,word ptr [r10+000019A2]
 Filesize:  55.63 KB
 Viewed:  1422 Time(s)

Sample Code.PNG




Last edited by Gear2ndGandalf on Sat Feb 17, 2024 8:12 am; edited 1 time in total
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4296

PostPosted: Tue Feb 06, 2024 11:35 pm    Post subject: Reply with quote

https://www.felixcloutier.com/x86/div

The numerator is always rdx:rax (rdx is the more significant half; edx:eax for 32-bit div). The denominator is some generic register or memory location- you're free to use whatever you want (probably not edx / eax obviously).

If you're dividing by 2, just shift the bits to the right by 1:
Code:
newmem:
code:
  movsx r8d,word ptr[r10+19A2]
  sar r8d,1
  jmp return

Some generic divisor:
Code:
alloc(damageDiv,4)

newmem:
code:
  // no need to backup rax: game overwrites it immediately after this
  push rdx
  movsx eax,word ptr[r10+19A2]   // eax b/c `idiv` uses edx:eax
  cdq                            // sign-extend to edx:eax
  idiv dword ptr[damageDiv]      // divide edx:eax by the specified 4-byte value
  mov r8d,eax
  pop rdx
  jmp return

damageDiv:
  dd 7

If you want some user-configurable divisor, I'd really recommend using floating point arithmetic. This allows you to use divisors like 1.5 for example if 2 is too much.
Code:
alloc(damageDiv,8)

newmem:
code:
  movsx r8d,word ptr[r10+19A2]
  cvtsi2sd xmm0,r8d       // convert int to double
  divsd xmm0,[damageDiv]
  cvttsd2si r8d,xmm0      // convert double to int (truncation)
  jmp return

damageDiv:
  dq (double)1.5
xmm0 probably isn't in use, so no need to back it up
_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25289
Location: The netherlands

PostPosted: Wed Feb 07, 2024 12:54 am    Post subject: Reply with quote

you don't need to use floats if you don't want to use floats

you can also multiply the value by 10 and then divide by 15 (divisor * 10) to get a divide by 1.5 with decent accuracy

(10 is just for accuracy. you can also multiply by 2 and then divide by 3(divisor * 2) depending on how accurate the input is)

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Gear2ndGandalf
Newbie cheater
Reputation: 0

Joined: 22 Jan 2018
Posts: 19
Location: USA

PostPosted: Wed Feb 07, 2024 1:00 pm    Post subject: Reply with quote

Thanks that code actually works! And thanks for the explanation as well.
Back to top
View user's profile Send private message
Gear2ndGandalf
Newbie cheater
Reputation: 0

Joined: 22 Jan 2018
Posts: 19
Location: USA

PostPosted: Sat Feb 17, 2024 8:11 am    Post subject: Reply with quote

@ParkourPenguin

I have another one I'm struggling with.

Dante only goes into Majin Form devil trigger when his base HP is below 350. Starting max HP is 5000; Upgradable to 20000. I want to write a script that will allow us to set a percentage of Max HP needed to trigger the Majin Form.

Original code is:
Code:
mov eax,0000015E // (350)


My code is:
Code:
aobscanmodule(majinDT,dmc2.exe,B8 5E 01 00 00 66 39 83)
alloc(newmem,$1000,majinDT)
alloc(percent,$1000)

label(code)
label(exit)
label(return)

percent:
  dd (float)100

newmem:
  push rdx
  push ecx
  mov edx,64 // 100 int
  mov eax,[rdi+144]  // 5000 int (Is Max HP Address)
  mov ecx,[percent]  // 100 float
  div ecx
  mov eax,edx
  pop ecx
  pop rdx

code:
  // mov eax,0000015E // Original Code!

exit:
  jmp return

majinDT:
  jmp newmem
return:
registersymbol(majinDT)
registersymbol(percent)


Please see attachment for total code in disassembler. I keep getting improper results as changing my variable [percent] to 1 does not output 1% of 5000 to eax!

If [percent = 1] eax should = 50. If [percent = 100] eax should = 5000



Sample Code.PNG
 Description:
Percentage Code
 Filesize:  155.46 KB
 Viewed:  1080 Time(s)

Sample Code.PNG


Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4296

PostPosted: Sat Feb 17, 2024 12:31 pm    Post subject: Reply with quote

`div` is for integers. If you want floating point arithmetic, use SSE instructions.

Push `rcx`, not `ecx`. There might be something important in the upper 32 bits (e.g. a 64-bit pointer).

You don't need to allocate a full page (4096 bytes) of memory for a single variable.

There's no good reason to use floats instead of doubles.

Why move 100 into edx before the `div`? edx is the upper 32 bits of the numerator.
After `div`, eax is the result and edx is the remainder (i.e. modulus operation). You want eax and not edx.

I'm guessing the user input should be a number between 0 and 100. Floating point arithmetic:
Code:
aobscanmodule(majinDT,dmc2.exe,B8 5E 01 00 00 66 39 83)
alloc(newmem,1024,majinDT)
alloc(percent,8,majinDT)
alloc(hundred,8,majinDT)

label(return)

percent:
  dq (double)100
hundred:
  dq (double)100

newmem:
  cvtsi2sd xmm0,[rdi+144] // max hp
  mulsd xmm0,[percent]
  divsd xmm0,[hundred]
  cvttsd2si eax,xmm0
  jmp return

majinDT:
  jmp newmem
return:

registersymbol(majinDT)
registersymbol(percent)


I'd prefer floating point arithmetic, but if you want integer arithmetic, use integers instead of floats. Multiply by the percentage first, then divide by 100 to avoid loss of precision.
Code:
...
percent:
  dd (int)100

newmem:
  push rdx
  push rcx

  mov eax,[rdi+144]  // max HP
  imul [percent]  // edx:eax = maxHP * percent
  mov ecx,(int)100
  idiv ecx  // eax = edx:eax / ecx

  pop rcx
  pop rdx

  jmp return
...

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Gear2ndGandalf
Newbie cheater
Reputation: 0

Joined: 22 Jan 2018
Posts: 19
Location: USA

PostPosted: Tue Feb 20, 2024 11:14 pm    Post subject: Reply with quote

Really appreciate it! Thanks for all your help ParkourPenguin and Dark Byte! Now I'm going to open another topic with a CE question regarding how to make a pop up warning happen when enabling a script.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites