PROWAREtech
Intel IA-32 Assembly Tutorial - A Guide to the Basics of x86 Assembly - Page 07
Procedures
The Runtime Stack
The runtime stack (stack) is a memory array managed directly by the CPU using two registers:
SS
and ESP
. The SS register holds a segment descriptor and
is not modified by the programmer.
The ESP
(extended stack pointer) register holds a 32-bit offset into some
location on the runtime stack.
ESP
is not commonly modified directly; however, it
is indirectly modified by instructions like PUSH
, POP
, CALL
, and
RET
.
ESP
(the stack pointer register) points to the last integer to be added to the stack. When an item
is added to the stack is it pushed using instruction PUSH
when it is removed, it is popped from
the stack using instruction POP
.
The PUSH
instruction decrements the stack pointer by four (bytes) and copies a value into the location
in the stack pointed to by the stack pointer. In this figure, ESP
points at memory offset 1000h and is then
decremented by 4 so that ESP
points at memory offset FFCh, and the 32-bit value 00000001h was pushed on to the stack.
Then it points to FF8h... (and so on).
|
.code
push eax ;push the value of EAX on to the stack
push var1 ;push the value of var1 on to the stack
The POP
instruction increments ESP
and removes a value from the stack placing it in a register or variable.
|
.code
pop var1 ;pop the value ESP is pointing to into var1
pop eax ;pop the value ESP is pointing to into EAX
Uses of the runtime stack are:
- A temporary place to store register values
- When a
CALL
instruction executes, the CPU saves the current procedure's return address on the stack. - Procedure (function) arguments can be pushed on the stack.
- Local variables inside a procedure are allocated on the stack and are discarded when the procedure ends.
PUSHFD
pushes the EFLAGS
register on the stack and POPFD
pops the stack into EFLAGS
.
.data
flgs DWORD ?
.code
pushfd ;push eflags onto stack
pop flgs ;pop it into flgs variable
.
.
.
push flgs ;push flgs variable onto stack
popfd ;pop stack value into eflags
PUSHAD
instruction pushes all of the 32-bit general purpose registers on the stack and POPAD
pops
then all from the stack.
func_one PROC
pushad ;push all the register values on to the stack
.
. ;use the registers
.
popad ;now, restore them
ret
func_one ENDP
To use the register EBP
(Extended Base Pointer), first push it on the stack before using it then MOV
the ESP
into it. Be sure to POP
EBP
when finished with the procedure.
Here is a procedure that demonstrates this:
TITLE 'extern "C" unsigned __stdcall strlen2(const char *string);'
.386P
.model FLAT
PUBLIC _strlen2@4
_TEXT SEGMENT
_strlen2@4 PROC NEAR
push ebp ; push EBP on the stack
mov ebp, esp ; move ESP into EBP
push edi
mov edi, DWORD PTR [ebp+8] ; *string - use EBP
mov ecx, 0FFFFFFFFh
xor eax, eax
cld
repne scasb
xor ecx, 0FFFFFFFFh
dec ecx
mov eax, ecx
pop edi
pop ebp
ret 4
_strlen2@4 ENDP
_TEXT ENDS
END