Help File:ASM Basics 2

From Cheat Engine
Revision as of 02:41, 20 March 2017 by TheyCallMeTim13 (talk | contribs)
Jump to navigation Jump to search

Originally posted by DABhand


FLOATS

Ok whats a Float all about, well its simple, a float uses REAL values, what is a REAL value?


A REAL value is a number which is not an integer, i.e. it contains numbers after a decimal point, like for example a float opcode can work out 5 divided by 4 and give the answer 1.25, also a REAL value can contain NEGATIVE numbers also like -3.567


An integer with the same math problem will report 1 as the quotient with a remainder of 1. So you can see Floats are very usefull indeed :)


Why are we talking about floats? Some games and indeed applications will use float values to either work out monetary values or even in a game like percentage values and so forth.


Both my latest trainers for Act of War and Settlers 5 (Die Siedler 5) use float values.


FLOAT OPCODES

Here is a list of opcodes and what they do :)


 FLD [source]               Pushes a Float Number from the source onto the top of
                            the FPU Stack.
 FST [destination]          Copies a Float Number from the top of the FPU Stack
                            into the destination.
 FSTP [destination]         Pops a Float Number from the top of the FPU Stack
                            into the destination.
 FLDZ                       Pushes +0.0 on top of FPU Stack
 FLD1                       Pushes +1.0 on top of FPU Stack
 FLDPI                      Pushes PI on the top of FPU Stack
 FILD [source]              Pushes an integer from the source to the top of the
                            FPU Stack.
 FIST [destination]         Copies an integer from the top of the FPU Stack to
                            the destination.
 FISTP [destination]        Pops an integer from the top of FPU Stack into the
                            destination.
 FCHS                       Compliments the sign-bit of a float value located on
                            the top of the FPU Stack or ST(0) Register.
 FNOP                       Performs no FPU Operation.[It's a 2 byte instruction
                            unlike that of NOP which is a 1 byte instruction.]
 FABS                       Replaces the float value on the top of the stack with
                            it's absolute value.
 FADD [operand]             Adds the value of the operand with the value located
                            on the top of the FPU Stack and store the result on
                            the top of the FPU Stack.
 FCOS/FSIN                  Replaces the value on the top of the FPU Stack with
                            it's cosine/sine value.
 FDIV [operand]             Divide the value on the top of the FPU Stack with the
                            operand and store the result on the top of FPU Stack.
 FMUL [operand]             Multiply the value on the top of the FPU Stack with
                            the operand and store the result on top of FPU Stack.
 FSUB [operand]             Subtract operand value from the value on top of FPU
                            Stack and store the result on top of FPU Stack.
 FXCHST (index)             Exchanges values between top of FPU Stack and the
                            ST(index) register.
 FCOM                       Compares the float value located on top if FPU Stack
                            with the operand located in memory or the FPU Stack.
 FCOMP                      Same as FCOM but pops the float value from the top of
                            the FPU Stack.
 FNSTSW AX                  Store FPU Status Word in AX. (Used for Conditions)


Hope thats explanatory enough :)


Before I show an example or two, lets talk about Stacks. What are they?


STACKS

Well a stack is used for a temporary location for values, a game or application may want to use a register for something else but want to keep the previous value for future reference, so the program will PUSH a value onto the stack for later retrieval.


The stack is 8 small stacks in the 1, so look at it as a small filing cabinet in a way. Any of these values can be retrieved by calling for the stack and its position, like the following


 st(0) - always the top of the stack
 st(1) - next after top
 st(2) - 2nd from the top
 ..
 st(7) - Bottom of the stack


So when you want to get a value you can if you know where it is stored, it does become a little complicated if you keep PUSH'ing values to the top of the stack as the previous value is moved down 1. So to take a value we just POP it back.


So remember

PUSH - Places a value on a stack POP - Removes a value from the stack


But those opcodes are handy for integer values, what about floats?


The next section will show you.


FLOAT EXAMPLES

OK how to PUSH and POP values from the stack, its not difficult, heres a few examples :)


Example 1

Say we have a value in a known address which is a REAL value (so float) and want to add a value to it? For arguments sake lets say the register EAX contains the address 450000h which contains money in a game and we want to add a value from revenue which resides in an address contained in register EBX at 450008h and then send back to the original address?


Here is how


 FLD [eax]   - This opcode PUSH's the value at the address 450000h contained in
               EAX and pushes it to the top of the stack
 FADD [ebx]  - This then adds the value at the address 450008h contained in EBX
               with the value at the top of the stack, then replaces the value
               at the top of the stack with the new value from the FADD opcode.
 FSTP [eax]  - This then POP's the value on top of the stack to the address 450000h
               contained in the register EAX, where your old money value was and
               replaces with new one.


Example 2

Say now we want to calculate a Health Points value after taking damage, but wait! The damage is a float value but health is integer :o So how does this work out?? Its not difficult ill show you how :) Again we will use the last registers for this example, EAX (450000h) contains our Health integer value and and EBX (450008h) contains our damage float value.


Here it is


 FILD (EAX)  - This opcode PUSH's an integer value to the top of the stack from the
               address 450000h contained in EAX.
 FSUB (EBX)  - This subtracts the value at address 450008h (float) contained in EBX
               from the value at the top of the stack.
 FISTP (EAX) - This opcode POP's an integer value from the the top of the stack to
               the address 450000h contained in EAX. If the REAL value was 1.50 or
               higher it will send as an integer of 2, if 1.49 or lower then it will
               send as 1.


Great huh :) See its not that difficult to understand :)


Example 3

This one is a toughy, we have a game but one of the addresses in the EAX register is needed for later on, but we also need the EAX register to work out a new ammo value, and no other register is free to send the address to, omg what to do what to do!!

Dont worry, believe in the stacks :) The following will contain POP and PUSH command :)

So for this example, EAX contains the value 800000h, the ammo value is contained at the address 450000h and the EBX contains the address 450008h which contains the either positive or negative number to be added to the ammo amount, if negative a shot was fired, if positive then a reload of the weapon or ammo picked up.


 PUSH EAX         - This opcode PUSH's the value of EAX (notice without the [ ] it moves
                    the value in EAX to the stack but if it had the [ ] it would move
                    the value contained at the address of the value in EAX). In this
                    case 800000h is PUSH'd on top of the stack.
 MOV EAX, 450000h - This opcode moves the value 450000h into the register EAX, which
                    replaces the old 800000h value.
 FILD [EAX]       - This opcode as you know will PUSH the value at the address contained
                    in the register EAX, see the difference its using the [ ] so the
                    game will look at the address 450000h and take the value there, and
                    the PUSH to the top of the stack.
 FADD [EBX]       - This again is self explanatory now, it adds the value at address
                    450008h with the value on the stack, if it was a negative number it
                    will decrease the value, if positive increase it, just basic maths :)
 FISTP [EAX]      - Again this POP's an integer value from top of stack to the memory
                    location contained in EAX, which is 450000h.
 CALL 46AEFF      - What the hell is this??? I hear you say, wait a bit ill tell you
                    just after :)
 POP EAX          - This opcode POP's the original 800000h back into the register EAX, so
                    the game hasnt lost that value.


OK, the CALL opcode, its a handy opcode for the fact that if your program or game uses a routine to work out something but is always used it would be messy code if we were to keep manually typing it out not to mention a much bigger file.


The CALL opcode, calls the opcodes at a certain address to work out the same function it does later on, so you only need to have that 1 set of opcodes for the entire program or game, you just CALL it, saves time and space.


At the end of these opcodes from a CALL will be an opcode call RET (return) it will make the program or game go back to where it left off, in this case to the POP EAX opcode.


Thats end of day 2 :)


Hope you understood and it helped you see how things work.


Any questions just post and ill answer when available :)


Next time I will talk about different Jumps and Compares :)


After that Ill show you how to code inject to make a trainer :D But as I said learn these well and you will understand what im talking about when code injecting ;)

Links