Over the years of playing with delphi/assembler... etc. I have learnt some very usefull ways to debug code when for some reason or another you can not put a breakpoint in the IDE (eg: self modifying code, injected dll, remote process).
Please note though, I am completly self-taught, so this information may not be complete, and some terms may be inaccurate
The CPU window
When I first saw this window, it scared me, full of numbers and this "assembler" stuff that only the pros knew. The Delphi documentation on it is very limited since it requires an understanding of x86 operations.
In Delphi, bring up the CPU window (CTRL+ALT+C) and I will explain what each part of it is.
The top left pane
This window contains the actuall CPU instructions, this is assembler. If you widen the CPU window, an extra column of numbers will be displayed.
The first column is the address in virtual memory that the line is at, the one that the green arrow points to is the current EIP (Enhanced Instruction Pointer), the EIP is the address of the code the CPU is about to execute.
The seccond column (the one that shows up if you expand the window) is the hex OP codes, these are the compiled assembler instuctions and is what the CPU reads. For example, 0x50 is "push eax" and 0x90 is "nop".
The third column is the human readable assembler, assembler is always in the format <OPERATION><VALUES>, if there are no values for the operation, then its just the operation.
eg, here is a small sample:
- Code: Select all
push eax <-- eax is a param
pop eax <-- eax is a param
pushad <-- no params for this operation
popad <-- no params for this operation
ret 8 <-- byte param for this one, but is optional.
The bottom pane
This contains the actual memory and is really usefull if you want to check that a variable is being set properly, you can look up the address of a variable to see its raw value, for example:
- Code: Select all
MyVar := 'example';
Put a breakpoint on the beep line run the app and write down the address displayed. The "beep" is just to give us somthing to break on that delphi won't optomise out. If you open the CPU window, right click in the memory pane, select "Goto Address" and type in the address you wrote down. You should see the raw value of the variable, including the length bytes which you don't normally see using a delphi watch.
The bottom right pane
This is the cpu stack you have heard mentioned around the place. The stack is like a pile of paper, each one has some information on it, to access/read a single piece of paper you need to know its location or address, you can also take a page off the top, or put one on the top.
The CPU stack also has a size limit, just like a pile of paper, there is only so many pages, you have probarbly already seen the odd "Stack Overflow" error caused by overfilling the stack.
The below procedure will create a stack overflow error:
- Code: Select all
So how is it used?
The "push" operation is used to put a new value onto the top of the stack, "pop" operation is used to remove a value from the top of the stack. You may have noticed that in the top middle pane there is a value called "ESP", this stands for Enhanced Stack Pointer. ESP always is equil to the current location of the stack.
Dont be fooled though, the stack is backwards, when you push a value onto the stack, the address decreases, when you pop a value off, the address increases.
The stack is also used by the "call" and "ret" operations, "call" pushes the current EIP + 5 onto the stack and then changes the EIP to the address it was given. The "ret" operation sets the value of EIP to the address that the "call" operation pushed onto the stack and then pops it from the stack. This provides a way to re-use code in assembler.
The top middle window
Ok, you have explained EIP and ESP, but there are others there, what are they?
These are the CPU registers, they are used for storing temporary values for calculations and other things. Since they are physically inside the CPU, they are MUCH MUCH MUCH faster then RAM/Memory, so efficient use of these will make for a very fast program.
The basic registers are:
EAX - Generic 32 bit (8 byte) register
EBX - Generic 32 bit (8 byte) register
ECX - Generic 32 bit (8 byte) register
EDX - Generic 32 bit (8 byte) register
EDI - Not sure myself, I have never used it, google it
EBP - Again, not sure
ESP - Stack Pointer
EIP - Current CPU address
EFL - Again, nto sure.
These all start with an "E" because they are "Enhanced", this means they are 32 bit registers that store 8 bytes, AX, BX, CX.... etc all exist aswell, they can be used to access only 4 bytes of the 8 if you only need 16 bits.
The top right pane
Thses are the cpu flags pane... I dont know much about these as I have never had to do anything with them.
Done for now
Ok, there is the basics you need to know to get started... in the next post I will explain some little tricks you can use to help debugging.