News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

General Purpose Registers? ALL OF THEM?

Started by OceanJeff32, April 04, 2005, 03:29:09 AM

Previous topic - Next topic

OceanJeff32

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:
Any good programmer knows, every large and/or small job, is equally large, to the programmer!

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

rags

Jeff,
Good luck in school...BTW What are you going to school for?
Rags
God made Man, but the monkey applied the glue -DEVO

Robert Collins

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.

Bieb

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?

thomasantony

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
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

Robert Collins

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. 

QvasiModo

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).

Infro_X

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.

tenkey

A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8