2012-02-05 47 views
13

Cuando se inicia el programa (linux, elf) - ¿hay ceros en eax, ebx, etc. o puede haber algo (no estoy haciendo ninguna llamada ni estoy utilizando bibliotecas externas)? En mi máquina es realmente así, ¿puedo transmitir tal comportamiento al escribir programas asm?¿Cuál es el estado de registro predeterminado cuando se inicia el programa (asm, linux)?

+1

En circunstancias normales, debe inicializar estos explícitamente. Por lo tanto, no debería importar cuál es su estado inicial. – nobar

+0

Estoy tratando de guardar algunos bytes en mi ejecutable y no quiero mover ceros a eax si puedo evitar esto. Necesito poner 1 en eax, si uso el comando movl, se traducirá a 5 bytes. Entonces quiero usar movb y poner 1 a al. El resultado es el mismo, el comando traducido a 2 bytes. Obtengo ganancia de 3 bytes. Pero solo se puede hacer si hay ceros en eax por defecto. –

+0

¿En qué circunstancias sería importante guardar esta cantidad de código? Solo inicialízalos. Si los bits superiores de EAX no importan, entonces puede inicializarlo con movb al, 1, pero no se preocupe por el espacio. –

Respuesta

17

Esto depende completamente del ABI para cada plataforma. Como mencionas eax y ebx, veamos cuál es el caso de x86. En fs/binfmt_elf.c línea # 972, en el interior load_elf_binary(), el núcleo comprueba si el ABI especifica cualquier requirements para valores de registro en la carga del programa:

/* 
* The ABI may specify that certain registers be set up in special 
* ways (on i386 %edx is the address of a DT_FINI function, for 
* example. In addition, it may also specify (eg, PowerPC64 ELF) 
* that the e_entry field is the address of the function descriptor 
* for the startup routine, rather than the address of the startup 
* routine itself. This macro performs whatever initialization to 
* the regs structure is required as well as any relocations to the 
* function descriptor entries when executing dynamically links apps. 
*/ 

A continuación, llama ELF_PLAT_INIT, que es una macro definida para cada arquitectura en arch/xxx/include/elf.h. Para x86, lo hace el following:

#define ELF_PLAT_INIT(_r, load_addr)  \ 
    do {         \ 
     _r->bx = 0; _r->cx = 0; _r->dx = 0; \ 
     _r->si = 0; _r->di = 0; _r->bp = 0; \ 
     _r->ax = 0;       \ 
    } while (0) 

Así, cuando su binario ELF se carga en Linux x86, que podía contar con todos los valores de registro es igual a cero. No significa que deberías, sin embargo. :-)

+3

Esta reducción a cero todavía ocurre (2015), pero NO es requerida por la ABI. (Ver el comentario de Ciro sobre la respuesta de Basile). –

+1

También tenga en cuenta que en un ejecutable enlazado dinámicamente, el enlazador dinámico se ejecuta antes de '_start', y deja la basura en los registros permitidos por el ABI. Solo los ejecutables vinculados de forma estática tienen sus registros en cero cuando la ejecución llega a '_start'. –

9

Para los sistemas AMD64 o x86-64 (64 bits) en Linux, el x86-64 ABI define el contenido inicial de los registros.

Hay especificaciones similares para i386 ABI, etc. ARM ABI

páginas

Ver Wikipedia sobre ELF y ABI

5

x86-64 System V ABI sección 3.4.1 "Pila inicial y Registro Estatal" (Basile linked to PDF):

  1. %rsp puntos a TH pila

    El puntero de pila contiene la dirección del byte de dirección más baja, que es parte de la pila. Está garantizado para ser de 16 bytes alineados en la entrada proceso

  2. %rdx un puntero de función que la aplicación debe registrarse con atexit si es distinto de cero.

    un puntero de función que la aplicación debe registrarse con

  3. %rbp no se especifica, pero el espacio de usuario debe fijar a la estructura de base.

    El contenido de este registro no se especifica en el momento de la inicialización del proceso, pero el código de usuario debe marcar el marco de pila más profundo ajustando el puntero del marco a cero.

  4. Todo lo demás indefinido.

Linux luego lo sigue "porque" el LSB dice eso.

+1

'% rdx' tiene permitido ser NULL, y en Linux actual es' 0' en un proceso nuevo desde un ejecutable enlazado estáticamente. Pero el enlazador dinámico se ejecuta antes de '_start' al ejecutar un ejecutable enlazado dinámicamente, por lo que puede establecer un valor en'% rdx' (y lo hace, de acuerdo con 'gdb/bin/bash'). No estoy seguro de si '_start' todavía se supone que lo trate como un puntero a la función en ese punto, pero probablemente sí, porque todo lo demás en ese punto sigue al ABI. –

+0

El i386 ABI (http://www.sco.com/developers/devspecs/abi386-4.pdf) tiene requisitos idénticos en los registros correspondientes de 32 bits: '% esp','% edx', '% ebp' y todo lo demás no está definido – pts

Cuestiones relacionadas