2010-11-10 24 views
5

estoy tratando de entender un poco de código:¿Hay algún valor predeterminado para los registros?

jg 0x00000047 
dec esp 
inc esi 
add [ecx],eax 

¿Cuál es el valor de EAX ? Estas son las cuatro primeras oraciones del programa y no sé si hay un valor predeterminado o si las oraciones anteriores le agregan algo a eax.

Mi sistema operativo es Linux y el ejecutable es compilada por gcc4.3 de un código fuente en C (gcc ejecutivo file.c)

+1

No 'is', pero' are'. – leppie

+0

Si proporciona información sobre su plataforma (sistema operativo, formato ejecutable) estoy seguro de que alguien puede decirle qué 'eax' está configurado en el punto de entrada del programa. – Edmund

+0

Editado, gracias por la sugerencia. –

Respuesta

3

Algunas instrucciones actualizan implícitamente los registros, incluso si los destinos no están listados explícitamente en el código. Algunos ejemplos:

  • cpuid devuelve los valores en EAX, EBX, ECX y EDX
  • loop decrementos ECX
  • rep instrucciones de cadenas cambian ecx, EDI y esi
  • rdmsr cambios EAX y EDX
  • mul y div cambiar eax y edx

Y hay muchos otros ejemplos.

No se puede asumir simplemente al ver que eax no figura en el código que no ha sido modificado.

Incluso suponiendo que conoce qué registros se ven afectados por la cual las instrucciones, las únicas veces que se tiene ninguna garantía por un valor son:

  • después de una instrucción que sabes lo actualiza
  • inmediatamente después de reinicio de hardware

En cualquier otro momento, nunca puede hacer suposiciones sobre los valores.

+0

Entonces, ¿diríamos que eax tiene un valor aleatorio (al menos aleatorio para mí)? –

+1

@Vaul: sí, nos gustaría –

5

depende de la plataforma, lenguaje y/o convención de llamada. Pero sí, el código anterior a esto normalmente debería haber configurado EAX a algún valor. EAX es uno de esos registros que se modifica con tanta frecuencia que normalmente no se usa para guardar cosas.

Las instrucciones parecen un poco aleatorias. En particular, el "dec esp" es normalmente un gran no-no, ya que la pila siempre debe estar alineada con dword. ¿Estás seguro de que este es el código real? Los bytes de la instrucción se traducen a "\ x7fELF" si estoy traduciendo a la derecha, lo que me sugiere que esto es solo los bytes del encabezado de un programa de Linux, no los bytes de código reales.

+0

Desensamblé un pequeño código de programa escrito por mí en C tratando de entender el código asm, supongo que no son instrucciones aleatorias. Como digo que no hay oraciones anteriores, eax podría tener un valor aleatorio. Gracias. –

+0

¿Cómo estás desmontando el código? Tenga en cuenta que un ejecutable rara vez es solo código sin formato. (El único formato que conozco es el de los archivos .com, que han quedado obsoletos durante más de 10 años). Existe un formato un tanto complejo para los ejecutables en la mayoría de los sistemas operativos de 32 bits. – cHao

+0

Usando x86dis, ¿está bien? –

2

No parece ser un código válido. ¿Estás seguro de que no era texto?

Decodificación como x86 de 32 bits da cuerda ELF:

00: 7F 45 // 0x7F E 
02: 4C  // L 
03: 46  // F 
04: 01 01 // ?? ?? 

intente abrir el archivo como archivo ELF y no tan solo binario.

4

Creo que lo que realmente está preguntando es calling convention, que describe cómo las subrutinas en un programa pasan información entre sí, y cómo el sistema operativo pasa información al programa y, en general, qué significan los diferentes registros .

Por ejemplo, el cdecl calling convention on the x86, que es utilizado por la mayoría de los compiladores de C, dice que cuando una función retorna, el valor de retorno va en el registro eax. Entonces, si tiene una función int foo(), sabe que después de foo ejecuta su código de operación ret, eax contendrá ese int que foo devolvió.

Por el contrario, el procesador PowerPC (generalmente) tiene (al menos) 32 registros, simplemente denominados r0, r1, ... r31. The AIX calling convention para este chip dice que el puntero de pila pasa a r1, que los parámetros de función pasan de r3 a r11, que los valores de retorno vuelven a r3, y así sucesivamente.

Es importante recordar que una convención de llamadas es una especie de acuerdo entre las funciones de un programa o entre bibliotecas. No es parte del hardware o una ley, y generalmente hay muchas convenciones de llamadas diferentes que se pueden usar en una plataforma. Es por esto que a veces se verá un código como

struct CFoo { void __stdcall method(); }; 

Eso es una instrucción para MSVC, que por lo general le gusta usar la convención fastcall, diciéndole que la utilice una convención diferente para que una función. Esto es importante si por ejemplo la función está definida en una biblioteca que fue construida por algún otro compilador que usa stdcall en su lugar.

Cuando hablamos de cómo el sistema operativo pasa información a un programa (o el hardware al sistema operativo), generalmente lo llamamos ABI en lugar de una convención de llamadas, pero es la misma idea. Entonces, en el caso de su programa, fue escrito asumiendo que el sistema operativo le pasaría alguna información particular sobre eax. Esa suposición sería particular para el sistema operativo, el compilador y posiblemente incluso para el programa individual.

+0

Muchas gracias, esto me da un buen punto para entender ASM. –

Cuestiones relacionadas