De assembler a C

Dudas y comentarios sobre otros lenguajes de programación. Si algún lenguaje recibe suficientes preguntas le añadimos nueva categoría.
Responder
Mensaje
Autor
Avatar de Usuario
Naitmeir
Mensajes: 110
Registrado: 20/11/2007 6:18 pm

De assembler a C

#1 Mensaje por Naitmeir » 29/05/2010 11:06 am

Muy buenas, a ver tengo que pasar este programa en C sabiendo que:

• Los enteros son de 32 bits
• Retorna el valor de la funció al registro eax.
• La funcion es responsable de liberar el espacio de las variables locales
• Es responsabilidad de quien pone los parametros de la pila de liberar espacio.
• El registro eax no hace falta salvarlo con el estado de la cpu, dado que siempre se hace servir para el retorno del resultado

... pero el primer problema que me encuentro es que no entiendo que hace esta instruccion del procedimiento main
lea eax, [ebp–4]
ya que diria que en esa desplazamiento no se ha puesto nada... y ya a partir de ahi me pierdo, les dejo el codigo ...

Código: Seleccionar todo

.model large
.386
.stack 100h
.code
sum proc

push ebp
mov ebp, esp
push ecx
mov eax, dword ptr [ebp+8]
add eax, dword ptr [ebp+0Ch]
mov ecx, dword ptr [ebp+10h]
mov dword ptr [ecx], eax
xor eax, eax
pop ecx
mov esp, ebp
pop ebp
ret

sum endp

main proc

push ebp
mov ebp, esp
sub esp, 4h
lea eax, [ebp–4]
push eax
mov eax, 02h
push eax
mov eax, 03h
6
push eax
call sum
xor eax, eax
mov esp, ebp
pop ebp
ret

main endp
.startup
call main
.exit
end
No sabia donde poner el post, el moderador ya decidira donde va mejor, y gracias de antemano

Avatar de Usuario
cheroky
Mensajes: 2571
Registrado: 22/09/2005 11:00 pm
Ubicación: Valladolid (España)

#2 Mensaje por cheroky » 29/05/2010 7:27 pm

Naitmeir escribió: ... pero el primer problema que me encuentro es que no entiendo que hace esta instruccion del procedimiento main
lea eax, [ebp–4]
Estoy mas acostumbrado a la sintaxis AT&T pero veo que la instrucción lea mueve al destino (en este caso eax) el offset de [ebp-4]. Si observas previamente se reserva espacio en la pila para 4 bytes, por tanto esta ultima instruccion es un puntero a dicho espacio, este valor luego es "pusheado" también a la pila. En C se traduce a:

Código: Seleccionar todo

int v; 
int* p = &v;
continua...

*EOF*
Imagen

Avatar de Usuario
Naitmeir
Mensajes: 110
Registrado: 20/11/2007 6:18 pm

#3 Mensaje por Naitmeir » 29/05/2010 11:51 pm

Ok, era algo que me imaginaba pero no estaba seguro.

A ver de esta el bloque de activación( BA) se quedaría de esta forma no?

////////////////BA MAIN PROC////
-0Ah= 03h
-08h= 02h
04h= *p
00h= OLD EBP
04h= @Retorno

/////////////////BA SUM PROC////
-04h= ECX
00h= OLD EBP
04h= @Retorno

... luego para terminar de entender el código necesito saber que hace:
mov eax, dword ptr [ebp+8]
pienso que mueve eax=03h ya que si el BA de la suma esta por encima de main proc ese es el desplazamiento que le corresponde, pero tampoco estoy seguro...

y también como interpretar un xor en c (se lo que se significa pero no se como traducirlo) en http://es.wikipedia.org/wiki/Operadores_de_C_y_C%2B%2B hace referencia a esto
XOR binario a ^ b
para esta instrucción?
xor eax, eax
nose, es raro de cojines.

Avatar de Usuario
cheroky
Mensajes: 2571
Registrado: 22/09/2005 11:00 pm
Ubicación: Valladolid (España)

#4 Mensaje por cheroky » 30/05/2010 4:44 am

Código: Seleccionar todo

mov eax, dword ptr [ebp+8]

Aquí copias en eax el contenido de ebp+8

Código: Seleccionar todo

xor eax, eax
Es la forma mas eficiente de "setear" todo el registro a 0;


*EOF*
Imagen

Avatar de Usuario
Naitmeir
Mensajes: 110
Registrado: 20/11/2007 6:18 pm

#5 Mensaje por Naitmeir » 30/05/2010 5:02 am

Gracias cheroky por la aclaracion de lo que hacia el xor en este caso, en papel ya veia que se quedaba a cero, pero me despisto un poco lo que lei en la wiki.
Entonces los dos procedimientos son void verdad?

Sobre: mov eax, dword ptr [ebp+8] ya veo que mueve el contenido de ebp+8 por eso te preguntaba si los bloques de activacion de los procedimientos se solapaban y coincide en 03h como te habia preguntado antes.

De todas formas muy agradecido por la ayuda! Un saludo

Avatar de Usuario
cheroky
Mensajes: 2571
Registrado: 22/09/2005 11:00 pm
Ubicación: Valladolid (España)

#6 Mensaje por cheroky » 30/05/2010 5:33 am

La sintaxis de (BA) no me es familiar ¿es de masm o turbo assembler?

*EOF*
Imagen

Avatar de Usuario
Naitmeir
Mensajes: 110
Registrado: 20/11/2007 6:18 pm

#7 Mensaje por Naitmeir » 30/05/2010 5:38 am

Ok. Esto de BA es lo mismo que decir bloque de activacion de la pila, donde se van haciendo los pushes you know... Yo solo he utilizado turbo assembler, pero este concepto lo tenemos sobre la teoria, no en la practica con compiladores

Avatar de Usuario
untio
Mensajes: 389
Registrado: 17/09/2008 9:35 am
Ubicación: Provincia de Almería
Contactar:

#8 Mensaje por untio » 04/06/2010 7:01 am

Hola,
Igual me paso de listo, pero cuando pasas parámetros a una función, la función llamada los recupera de la pila de forma convencional a partir de ebp + 8, después de guardar el registro esp.
El programa lo que hace es crear una variable y pasar su dirección, además de los números 2 y 3 al procedimiento. El procedimiento suma los valores de los dos números y guarda el resultado en la dirección apuntada por el puntero que le has pasado.

Espero que sea de utilidad a alguien.

Avatar de Usuario
cheroky
Mensajes: 2571
Registrado: 22/09/2005 11:00 pm
Ubicación: Valladolid (España)

#9 Mensaje por cheroky » 04/06/2010 10:28 am

Sí en este caso, y estrictamente no en general, asumiendo arquitectura i386 en algunos compiladores [ebp+8] se utiliza para accesar los primeros 4 bytes desde el actual marco de pila al marco donde se hizo la llamada, según la convención de llamada cdecl se refiere al primer argumento de la función, [ebp+12] el siguiente (si es un entero de 4 bytes), así sucesivamente, el elevado costo de una llamada a función en C se debe a toda esta secuencia.

Observando las instrucciones:

Código: Seleccionar todo

call foo
....
foo:
push ebp 
mov ebp, esp 
...
Este código es típico en compiladores como vc++, intel y gcc, 4 bytes para la dirección de retorno (call) más los 4 bytes para almacenar ebp (esp se actualiza, no se preserva) en la pila, pero ojo, no todos los compiladores siguen esta convención. Supongo que el usuario no ha vuelto a preguntar porque conocía este aspecto y felizmente acabó su practica.

*EOF*
Imagen

Avatar de Usuario
untio
Mensajes: 389
Registrado: 17/09/2008 9:35 am
Ubicación: Provincia de Almería
Contactar:

#10 Mensaje por untio » 05/06/2010 3:26 am

Hola a todos,
Me gustaría hacer una pequeña aclaración. El código no me acaba de gustar como ejemplo porque no se restaura esp después del retorno de la función -con add esp, 12 si la convención de llamada es cdecl o desde la función llamada con ret 12 si la convención es stdcall.
En este caso no es necesario porque el programa acaba, pero quería aclarar esto.

Espero que sea útil.

Avatar de Usuario
cheroky
Mensajes: 2571
Registrado: 22/09/2005 11:00 pm
Ubicación: Valladolid (España)

#11 Mensaje por cheroky » 05/06/2010 4:54 am

untio escribió:El código no me acaba de gustar como ejemplo porque no se restaura esp después del retorno de la función -con add esp, 12
No lo necesita, la pila ya no se usa en este contexto y los punteros de pila se quedan como estaban. Cumple con cdecl, el procedimiento invocante "limpia" los parámetros implicitamente en:

Código: Seleccionar todo

mov esp, ebp 
pop ebp 
algunos compiladores/ensambladores envuelven estas dos instrucciones con el nemónico leave y son simetricas o inversas a las que preparan el nuevo "stack frame":

Código: Seleccionar todo

push ebp 
mov ebp, esp




*EOF*
Imagen

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados