The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: OceanJeff32 on April 04, 2005, 03:29:09 AM

Title: General Purpose Registers? ALL OF THEM?
Post by: OceanJeff32 on April 04, 2005, 03:29:09 AM
So is it safe to say, that if you preserve all the information in each of the general purpose registers, you can still use them all for anything?

Like EDI, and ESI, these are normally pointers, but if you wanted to, you could use them for variables in functions, right?

Same for EBP, assuming you're not holding ESP's old value there or something.

I haven't done a lot of programming in ASM, mostly in C in the past, so forgive the simple questions, but these programming books I'm reading are telling me this is true, I just wanted confirmation I guess.

Later guys,

Jeff C
:green

P.S. I start school tomorrow after EIGHT YEARS of not being in school.   :dazzled: :dazzled:
Title: Re: General Purpose Registers? ALL OF THEM?
Post by: hutch-- on April 04, 2005, 04:23:01 AM
Jeff,

If you preserve them, you can routinely use EBX ESI & EDI and with a little trickery you can also use EBP (remove the stack frame). When you want to live dangerously you can use ESP as well but you must REALLY know what you are doing.
Title: Re: General Purpose Registers? ALL OF THEM?
Post by: rags on April 04, 2005, 02:03:20 PM
Jeff,
Good luck in school...BTW What are you going to school for?
Rags
Title: Re: General Purpose Registers? ALL OF THEM?
Post by: Robert Collins on April 04, 2005, 02:39:30 PM
I would think that since these are 'general purpose' registers then you can use them at will. If you have doubts about their previous contents then just make sure that you save and restore the contents before the system needs any of the registers.
Title: Re: General Purpose Registers? ALL OF THEM?
Post by: Bieb on April 05, 2005, 03:19:29 PM
Some of them aren't truly general purpose, though.  EBP, I believe, holds the pointer to the current stack location.  Kind of important.  I think there's also one that points to the next instruction to execute?
Title: Re: General Purpose Registers? ALL OF THEM?
Post by: thomasantony on April 05, 2005, 03:35:02 PM
Hi,
    ebx esi and edi are preserved by windows and it expects all programs to do so. esp holds the current stack pointer. ebp holds the value of stackpointer at the beginning of a stack frame so that the stack can be restored at the end of the procedure. So any imbalanced PUSHes or POPs inside the stack frame may not affect the program.

Thomas
Title: Re: General Purpose Registers? ALL OF THEM?
Post by: Robert Collins on April 05, 2005, 04:18:49 PM
Rule of thumb. Know and understand all of the registers be them general purpose or not. If in any given code you do not make any calls, do not do anything that would otherwise cause the OS to require any register then and you know this you are safe. It does not seem to me that a register that is used to 'point' to the next instruction would also be available to the programmer. 
Title: Re: General Purpose Registers? ALL OF THEM?
Post by: QvasiModo on April 05, 2005, 06:51:21 PM
Any register can be used, but some have consequences. For example, ESP (not EBP) has the current stack position in memory.

Others can be used safely, but work best for some specific uses (like ESI and EDI for string opcodes).

In any case, the operative system might add some extra restrictions (Windows wants you to preserve at the return point of your procedures the original values of EBP, EBX, ESI and EDI that they had on procedure entry).
Title: Re: General Purpose Registers? ALL OF THEM?
Post by: Infro_X on April 05, 2005, 07:20:34 PM
Summing Up:
ESP holds stack pointer, don't modify unless you know what your doing
EBP holds stack frame, don't modify unless you arn't using proc
EDI, ESI, and EBX hold things that windows requires to stay the same in callback functions. preserve these
EIP, just don't worry about this one, it'll take care of itself.


Quite Simply this is how I understand it to be.
During callback procudures one MUST preserve the EBX,EDI, and ESI registers. (This is where windows calls your function.)
Example of callback procudure:  WndProc proc hWnd,uMsg,wParam,lParam   <<<That is a callback procudure.

You used the stack frame, in MASM, if your called function has the proc keyword used, as above.
When you use the stack frame you SHOULD NOT change the EBP register. If you do, do not use locals or arguments.
Arguments are the variables that you passed to the procudure. In WndProc the arguments are: hWnd,uMsg,wParam, and lParam.
Locals are things you define, I'm sure you'll understand what they are soon enough, if you don't already.

EIP points to the next instruction to be executed. You cannot change EIP with mov, lea, or any of the other commands used to change GPRs.
You can change EIP with, jmp, jCC, call, ret, int, and intr.
I wouldn't mess with the int and intr until you fully understand what they do and how they work, or you'll probably crash your computer.
Changing EIP with jmp (jump) and jCC(jump on condition) is something quite common. jCC is used for if, while, and other such conditional changes in program flow.
Call and ret can be reduced down to jumps, pushes, and pops, that you can't do to EIP manually. Don't worry about it though.

Here is an example of everything so far. And then some.
lets say you want to create a window.
you first save everything into WNDCLASS
one of those things you save if WNDCLASS.lpwndproc
then you register your class.
now, everytime you call CreateWindowEx whatever you stored in WNDCLASS.lpwndproc gets called. like the following pseudo code.


Start:
invoke main
invoke ExitProcess,eax

main proc                ;push ebp
                             ;mov ebp,esp
                             ;sub esp,sizeof WNDCLASS (sizeof any and all LOCAL, currently we only got WNDCLASS)
LOCAL wc:WNDCLASS
mov wc.???,myvars
mov wc.lpfnwndproc,offset WndProc
mov wc.lpszClassName,offset ClassName
invoke registerclass,addr wc
invoke CreateWindow,stuff,addr ClassName,stuff,...morestuff...             ;Everytime you call this with the pointer to ClassName, this calls your WndProc,, EG: CallBack Procudure.
mov hWnd,eax
invoke MessageLoop
main endp

MessageLoop Proc
invoke GetMessage,addr msg,0,0,0
.IF eax==0 .BREAK
invoke DispatchMessage,addr msg              ;Everytime this is called the corrosponding window's class lpfnWndProc is called. When your windows' messages come your WndProc will get called. EG: another CallBack,, WndProc is a callback function, (eg. windows calls WndProc, and WndProc returns to windows, and windows returns to whatever function you called, and it returns to your code. EG: you didn't call WndProc, windows did.
.ENDIF
MessageLoop Proc

WndProc proc hWnd,uMsg,wParam,lParam  ;The stack frame is already setup with the proc keyword.
LOCAL status:DWORD
push hWnd
invoke somefunction,hWnd
ret
WndProc endp


Here is what WndProc looks like in assembly without the proc or local keywords

WndProc:
push ebp    ;Save EBP
mov ebp,esp
sub esp,4  ;save room for status;     ESP grows bigger as the number lowers, we'll see why in the next instructions
push [ebp+8]  ;not a typo
    ;each time you push, esp decreases
    ;after this instruction is executed, [ESP] will hold hWnd
push [ebp+8]  ;still not a typo
    ;now [ESP] and [ESP+4] both hold hWnd
    ;if esp increased we'd have to do [ESP-4] and that is why [ESP] subtracts to add new things.
    ;[EBP-4] holds status
    ;[EBP] holds what EBP used to be before mov ebp,esp
    ;[EBP+4] holds where to return when we change the EIP with call
    ;[EBP+8] holds hWnd
    ;[EBP+12] holds uMsg
    ;[EBP+16] holds wParam
    ;[EBP+20] holds lParam
call somefunction  ;Same as push eip+5
               ;jmp somefunction
               ;so [ESP] (not EBP) would hold where to return when we change EIP,, basically in somefunction, it'll return here and everything (except EAX) will be the same
mov esp,ebp ;esp needs to be where it was for ret to work
pop ebp ;ebp needs to be where it was as well
ret 16 ;ret is like, pop [eip] and then, add esp,16 which removes all the arguments/paramaters from the stack.


Summing Up:
ESP holds stack pointer, don't modify unless you know what your doing
EBP holds stack frame, don't modify unless you arn't using proc
EDI, ESI, and EBX hold things that windows requires to stay the same in callback functions. preserve these
EIP, just don't worry about this one, it'll take care of itself.
Title: Re: General Purpose Registers? ALL OF THEM?
Post by: tenkey on April 05, 2005, 09:20:34 PM
EIP is not a general purpose register.