Tengo una duda con el uso de funciones en ASM
hago una funcion y en el hago dos push
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?
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
comparar:
push ebx
Pero tengo una duda, si hago eso, ¿entonces quedaría así en el stack?
|
|push dword[ebp + 0x0C] - esp 0x0C
|---------
|
|push ebx - esp 0x08
|----------
|
|push ebx - esp 0x04
¿Y al final solo necesitaría hacer esto?
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?
|push dword[ebp + 0x0C] - esp 0x08
|---------
|
|push ebx - esp 0x04
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:
push 0xFFFFFF01
push 0xFFFFFF02
En este momento tenemos:
+----------
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:
+----------
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:
+----------
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:
; 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:
; 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í.
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