Can I pop out of the middle of the stack?

On x86 assembler:

I assume I have a normal function prolog, read

push ebp
mov  ebp,esp

I know that I can read or write registers by accessing the memory destination operand, let's say I need the first argument. I would do

mov eax,[ebp +8]

to get f. integer parameter from the stack.

So why don't I work with the stack pointer directly?

add  esp,8              ; point ESP at the data we want
pop  eax
sub  esp,12             ; restore ESP to its original position

Does this lead to errors? Is it used anyway?

Of course, I know that the first operation is smaller, since it is only one operation code, namely movinstead of three, but this is not the main thing.

( : mov eax, [ebp+8] - 3- x86. add/sub esp, imm8 - 3 , pop eax - 1 .
mov eax, [esp+8] - 4- : 16- , ESP . SIB.
, .)

?

+6
2

ESP .
, - , ESP , .

EBP, ESP.

, , ESP EBP.
ESP, , , ESP.

enter image description here
:

add  esp,8
mov ecx,[esp-4]     //never access data outside the actual stack.
pop  eax
sub  esp,12

, .
, , , . , , , , ().

: , ESP, , , ESP,
stack frame. (, ), , .
, ESP , ESP .


A - ESP
B - ESP.
A: B: .

?

add esp,8 //equivalent to pop anyreg, pop anyreg pop eax //pop from the (new) top of the stack. sub esp,12 //reset the stack back to where is was.

!

sub esp,12, 3 , , , .

.

mov eax,[esp+8]

A: , B: , C: , D: E: .

/
- FLAGS, , LEA . , add/sub, , (, , LEA 2 4 ALU Ryzen Haswell ). .

lea esp,[esp+8] == add esp,8 (but without altering the flags).  

lea edx, [esp+8]    ; copy-and-add replacing mov + add is very useful

LEA, 2 , /, .

+5

?

EBP , (, , , , ).

EBP - , - , , , / . ( ) EBP . / EBP (, "-fomit-frame-pointer" GCC).

:

    add esp,8
    pop eax
    sub esp,12

, , , . , , (, IRQ), , .

- :

    mov eax,[esp+8]

.

. ( ) ESP . :

;Copy array somewhere else, while reversing the order of elements
;
;Input
; ecx    Number of elements in array
; esi    Address of source array
; edi    Address of destination array

reverseArray:
    mov ebx,esp           ;ebx = stack top
    lea esp,[edi+ecx*4]   ;esp = address of byte after array
    cld
.next:
    lodsd                 ;eax = next element in source array
    push eax              ;Store it in destination array
    loop .next            ;Do all elements

    mov esp,ebx           ;Restore stack
    ret
+3

Source: https://habr.com/ru/post/1673081/


All Articles