domingo, 19 de octubre de 2008

Basics of ASM Day 2 - Floats

As I said before go here for a better layout

Here we go



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 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 But as I said learn these
well and you will understand what im talking about when code injecting

No hay comentarios: