News:

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

EBP and ESP with protected mode

Started by thomas_remkus, March 06, 2008, 03:50:46 AM

Previous topic - Next topic

thomas_remkus

I'm learning more MASM through the eyes of so co-workers and getting to answer their questions. I'm taking things I don't know to the forum for some help. Here's another question:

When I code in MASM I normally stick to EAX, EBX, ECX, and EDX. I'm learning more about ESI and EDI and that I can use them just as frequently as long as I don't need registers to the lower parts of the register. I have not run into an issue yet (so let me know if I'm doing something wrong). But I see that EBP and ESP are also available as general registers.

I have not used EBP or ESP for anything yet and know that in 16-bit mode these seem to be more significant. Base and section seem to really be not too important because I'm just using a flat model. Is there something else that these registers are used for that I might be stepping on if I start using them as just another general register?

thomas_remkus

I'd like to see what people say about this but after reading more from this forum I know this is way beyond my level right now. I'm having a hard time understanding what these two registers are used for ... but I know it's important. I think for now (until I understand what's going on) I'll just avoid them. Seems fair to me.

BogdanOntanu

ESP = extended stack pointer register

the CPU does use it automatically when you PUSH or POP or when you ENTER or LEAVE a PROCEDURE or on RET.

When you are advanced enough ESP can be used for tricks but you must be extremely careful.

You are right here: until you learn and understand more you should let the CPU do it own job with ESP and avoid using it as a general purpose register.

EBP - extended base pointer register

Can be used as a general purpose register but it was designed (mainly in 16 bits) to be used as a STACK FRAME base pointer (no not other "bases"). This default use as a stack frame base pointer did continue in 32 bits and it is used by MASM's PROC as a base for PROC argument and for LOCAL's.

It is slightly more easy to use EBP as a general purpose register but only IF you do not use PROC/ ENDP in standard ways.

However AGAIN...  until you do understand and learn more you should "stick to fishing into normal waters from now on". That means: avoid using EBP as a general purpose register until you have a desperate need in an optimized inner loop and you can handle the consequences. Or at least until you can understand stack frames into great details.

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

jj2007

Thomas,
You will rarely need ESP and EBP - LOCAL variables do the job unless you are in desperate need for many fast registers.
Some important hints in a nutshell:

1.
pushad
... you are free to use any registers here except ESP
(and EBP if you do NOT use LOCAL variables)...
popad


2. There is a convention that ACD are promiscuous registers - anybody can use them freely, including the Windows API's. So if you call any macro (e.g. chr$) or API (e.g. MessageBox), you can bet that eAx, eCx and eDx are not the same afterwards.

3. The other side of the coin is that BSD, i.e. eBx, eSi and eDi are protected - after the API call they are still the same. Fine for you - but attention, Windows also counts on you, so you must save these registers before using them! Purists often use
push ebx
push esi
push edi
...
pop edi
pop esi
pop ebx
in their code, instead of the pushad/popad sequence.

4. LOCAL variables are not initialised. If you want zeroes in your LOCAL variables and structures, use the code below at your own risk (it works perfectly but NOT with the MyProc proc uses edi syntax)

Happy coding,
JJ

.data?
EspGlob dd ?

MyCode proc
  LOCAL MyCt:DWORD
  LOCAL LocBuf[256]:BYTE
  LOCAL charfmt:CHARFORMAT2
  LOCAL MyPtr:DWORD
  call ClearLocals
...
MyCode endp

ClearLocals proc ; first instruction after LOCALS - eax will be zero on exit
pop EspGlob ; save the return address to a global variable - now
; the stack is identical to the calling procedure
xchg eax, ecx ; save ecx
mov ecx, ebp ; base page of calling procedure
sub ecx, esp ; ebp - esp = No. of bytes in locals
mov esp, ebp ; discard existing locals
shr ecx, 2 ; divide by four
@@: push 0 ; dwords on stack
loop @B
xchg eax, ecx ; restore ecx, 0 to eax
push EspGlob ; restore the return address
ret
ClearLocals endp

hutch--

The stack and base pointers are not easy to use in general purpose coding. With practice you can use EBP if you write a procedure without a stack frame where you have to keep track of ESP directly which can be complcated in larger code and in very limited circumstances you can save ESP to a global memory location to use it but it is difficult to use safely.

In most instances a standard MASM procedure which creates a stack frame does the job fine and in places where the stack frame maters you can usually inline the code to make it faster still. Your real win with writing stack frame free code is having EBP available which is important in larger procedures so you have an extra register to use in speed related areas.

The three registers that must be preserved between function calls in a stack frame are EBX ESI and EDI so if you write a procedure that uses any of the three, preserve any of the three  registers that are used and restore them at the end of the procedure. Normal stuff,


push ebx
push esi
push edi

; your code

pop edi
pop esi
pop ebx
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php