[SOLUCIONADO] Duda sobre uso de funciones y stack

Iniciado por proxy_lainux, Agosto 23, 2016, 10:18:18 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Agosto 23, 2016, 10:18:18 PM Ultima modificación: Agosto 28, 2016, 07:35:16 PM por Gabriela
Tengo una duda con el uso de funciones en ASM

hago una funcion y en el hago dos push

Código: asm

push ebp
mov ebp, esp

push dword [ebp + 0x0C]
push ebx
call comparar

mov esp, ebp
pop ebp


En el stack quedaría algo así, ¿cierto?

Código: asm
push dword[ebp + 0x0C] - esp 0x08
|---------
|
|push ebx - esp 0x04


Se me ocurrio hacer una comparación como en C, entonces lo haría parecido a strcmp afuera del push ebp, como volveré a usar ebx lo vuelvo a guardar

Código: asm

comparar:
push ebx


Pero tengo una duda, si hago eso, ¿entonces quedaría así en el stack?

Código: asm
|
|push dword[ebp + 0x0C] - esp 0x0C
|---------
|
|push ebx - esp 0x08
|----------
|
|push ebx - esp 0x04


¿Y al final solo necesitaría hacer esto?

Código: asm

comparar:
push ebx
loop:
mov eax, [esp + 0x0C]
mov al, byte [eax]
mov ebx, [esp + 0x08]
cmp al, byte [ebx]
....

pop ebx


Si así quedaría todo entonces al hacer pop, ¿quedaría de esta forma nuevamente y regresaría a la funcion anterior?

Código: asm
|push dword[ebp + 0x0C] - esp 0x08
|---------
|
|push ebx - esp 0x04

Agosto 27, 2016, 04:23:50 PM #1 Ultima modificación: Agosto 27, 2016, 04:27:25 PM por grep
Hola, perdón por responder algo tarde.

No logro interpretar tu muestra del stack, por eso voy a ir paso por paso.


Si, por ejemplo, ejecutas:

Código: asm
push 0xFFFFFF01
push 0xFFFFFF02


En este momento tenemos:

Código: text

    +----------
low |0xFFFFFF02 <------+ DWORD PTR [ESP + 0x00]
    |
    |0xFFFFFF01 <------+ DWORD PTR [ESP + 0x04]
    |
    |
    |
    |
high|
    +----------


NOTA: solo uso DWORD PTR para denotar que se referencia a registros de 32 bits.

Al ejecutar un CALL e inmediatamente un PUSH tenemos:

Código: text

    +----------
low |Valor insertado por PUSH <-----+ DWORD PTR [ESP + 0x00]
    |
    |Valor insertado por CALL
    |
    |0xFFFFFF02 <-------------------+ DWORD PTR [ESP + 0x08]
    |
    |0xFFFFFF01 <-------------------+ DWORD PTR [ESP + 0x0C]
high|
    +----------


"Valor insertado por CALL" es la dirección de memoria de la instrucción que se encuentra después de la instrucción CALL.

Al ejecutar POP tenemos:

Código: text

    +----------
low |
    |
    |Valor insertado por CALL <-----+ DWORD PTR [ESP + 0x00]
    |
    |0xFFFFFF02 <-------------------+ DWORD PTR [ESP + 0x04]
    |
    |0xFFFFFF01 <-------------------+ DWORD PTR [ESP + 0x08]
high|
    +----------


Para la pregunta ¿Quedaría igual que la primera figura? la respuesta es no. Como se puede ver, hay un registro adicional en [ESP + 0x00] que es "Valor insertado por CALL".

Si "comparar" es una función, entonces necesitas del "Function prologue" al principio:

Código: asm

; Function prologue
push ebp                         ; or PUSH BP         in 16 bits
mov ebp,esp                      ; or MOV BP,SP       in 16 bits


y el "Function epilogue" al final:

Código: asm
; Function epilogue
leave                            ; mov esp,ebp / pop ebp
ret


y además, en lugar de usar un "Effective Address" con ESP, sería mejor hacerlo con EBP ya que de esta forma los direccionamientos a los argumentos de las funciones son fijos.

Saludos

Ok, ahora entiendo... gracias por ayudarme.

No me había puesto a pensar que call también se encontraba en el stack

A lo que me referia con otra funcion fuera era algo así.

Código: asm
push ebp
mov ebp, esp

push dword [ebp + 0x0C]
push ebx
call comparar
cmp eax, 1
..... etc

mov esp, ebp
pop ebp

comparar:
push ebx
loop:
mov eax, [esp + 0x0C]
mov al, byte [eax]
mov ebx, [esp + 0x08]
cmp al, byte [ebx]
....

pop ebx
y luego de regreso
mov eax, 1 ;--- si no falló nada
ret


Pero suena comprensible lo que me explicaste... gracias nuevamente