Instrucciones de inserción en el ensamblaje (Intel 8086)

Necesito elegir el implemento correcto para llamar a una función foo que la escrita en c. foo obtiene 1 argumento 0x100fa500.

la primera respuesta es:

sub esp,2
mov word[esp],0xa500
sub esp,2
mov word[esp] , 0x100f
call foo
add esp 4

y el segundo:

 sub esp,2
 mov word[esp],0x100f
 sub esp,2
 mov word[esp] , 0xa500
 call foo

¿Por qué lo segundo es cierto? Creo que el primero implementa el parámetro de inserción correcto y luego llama

preguntado el 01 de julio de 12 a las 17:07

¿Etiquetar como tarea tal vez? -

2 Respuestas

Aparte de los desaparecidos add esp, 4 al final, la segunda versión es correcta, ya que la arquitectura Intel es little-endian. Esto significa que una DWORD se almacena en la memoria con su BYTE o WORD menos significativo ocupando la dirección de memoria más baja. En tu caso, 0xA500 es la PALABRA menos significativa de DWORD, y la segunda versión la coloca correctamente en los 2 bytes inferiores de un área de 4 bytes de la pila.

Respondido 01 Jul 12, 17:07

pero, ¿la pila no comienza desde la dirección alta? Quiero decir, si ejecuto el primer código, obtendré: 10 en la dirección más baja de la pila y 00 en la más alta. obtendré si lo hago: empuje 0x100fa500. ¿Tengo razón? y esto es también lo que - user1462787

@ user1462787: todo lo que dice es consistente con una arquitectura big-endian, que no es el caso aquí. El hecho de que esté tratando de poner 10 en la dirección más baja de la pila ya está mal. De hecho, el primer código colocará 0F en la dirección más baja de la pila; de hecho, está cometiendo el mismo error dos veces (una vez para el orden de bytes dentro de DWORD, relacionado con lo que requiere la pregunta, y otra vez para el orden de bytes dentro de una PALABRA, relacionado con cómo un mov opera la instrucción.) - ndkrempel

@user1462787: Quizás su confusión esté relacionada con el hecho de que la pila crece hacia abajo. En este sentido, la pila está "al revés", pero los elementos de datos individuales dentro de la pila se almacenan en su orden normal; de lo contrario, no podría acceder a ellos correctamente con DWORD y WORD estándar. movs. - ndkrempel

Creo que ahora entiendo. Sé que la pila crece hacia abajo. entonces, en el segundo código, 100f está en la dirección 1000, por ejemplo, y a500 está en la dirección 984. Entonces, cuando la función obtenga el argumento, debido al little endian, será 100f9500. ¿Tengo razón? pero esto es diferente de mov this to eax por ejemplo. porque cuando haga mov eax, [esp+2] obtendré algo más: 9500100f. - user1462787

@ usuario1462787: mov y pop no te comportes diferente de esa manera - mov también le dará 0x100FA500 en eax, ya que 00 está en el primer byte (dirección más baja) en la memoria, A5 en el siguiente más alto, luego 0F, luego 10 en el último byte (dirección más alta) en la memoria. - ndkrempel

Depende de la convención de llamada, pero para "cdecl" depende de la persona que llama limpiar la pila. Lo que significa que es su primera respuesta correcta porque "agrega esp, 4". Sin embargo, al igual que ndkrempel notó en su respuesta, el parámetro debe pasarse como little-endian como en la segunda respuesta.

http://en.wikipedia.org/wiki/X86_calling_conventions

Respondido 01 Jul 12, 17:07

Creo que la limpieza de la pila de llamadas o no es solo un error tipográfico en la pregunta. Fíjate en el orden de los movs difiere: creo que ese es el objetivo principal de la pregunta. - ndkrempel

@ndkrempel: Creo que tienes razón. He editado mi respuesta. Y esta es probablemente una pregunta de tarea :-) - villa krumlinde

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.