Help File:ASM Basics 2
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 ;)