Este team de expertos pasados muchos días de trabajo y de recopilar de datos, han obtenido la solución, queremos que resulte útil para ti para tu trabajo.
global
La directiva es específica de NASM. Es para exportar símbolos en su código a donde apunta en el código objeto generado. Aquí tu marcas _start
símbolo global por lo que su nombre se agrega en el código del objeto (a.o
). El enlazador (ld
) puede leer ese símbolo en el código de objeto y su valor para saber dónde marcar como punto de entrada en el ejecutable de salida. Cuando ejecuta el ejecutable, comienza donde está marcado como _start
en el código.
Si un global
Si falta la directiva para un símbolo, ese símbolo no se colocará en la tabla de exportación del código objeto, por lo que el vinculador no tiene forma de conocer el símbolo.
Si desea utilizar un nombre de punto de entrada diferente a _start
(que es el predeterminado), puede especificar -e
parámetro a ld como:
ld -e my_entry_point -o out a.o
Una etiqueta no es explícitamente global hasta que la declare global, por lo que debe utilizar la directiva global.
El enlazador necesita la etiqueta global “_start”, si no hay una dirección _start global, el enlazador se quejará porque no puede encontrar una. No declaró _start como global, por lo que no es visible fuera de ese módulo / objeto de código, por lo que no es visible para el vinculador.
Esto es lo opuesto a C, donde se implica que las cosas son globales a menos que las declare locales
unsigned int hello;
int fun ( int a )
return(a+1);
hola y la diversión son globales, visibles fuera del objeto, pero esto
static unsigned int hello;
static int fun ( int a )
return(a+1);
los hace locales no visibles.
todo local:
_start:
hello:
fun:
more_fun:
estos ahora están disponibles a nivel mundial para el vinculador y otros objetos
global _start
_start:
global hello
hello:
...
_start
es usado por los Binutils predeterminados ld
secuencia de comandos del enlazador como punto de entrada
Podemos ver la parte relevante de ese script del enlazador con:
ld -verbose a.o | grep ENTRY
que salidas:
ENTRY(_start)
El formato de archivo ELF (y otro formato de objeto, supongo), dice explícitamente en qué dirección comenzará a ejecutarse el programa a través del e_entry
campo de encabezado.
ENTRY(_start)
le dice al enlazador que establezca esa entrada la dirección del símbolo _start
al generar el archivo ELF a partir de archivos objeto.
Luego, cuando el sistema operativo comience a ejecutar el programa (exec
llamada al sistema en Linux), analiza el archivo ELF, carga el código ejecutable en la memoria y establece el puntero de la instrucción en la dirección especificada.
El -e
bandera mencionada por Sedat anula la predeterminada _start
símbolo.
También puede reemplazar todo el script del vinculador predeterminado con el -T
opción, aquí hay un ejemplo concreto que configura algunas cosas de ensamblaje de metal desnudo.
.global
es una directiva de ensamblador que marca el símbolo como global en el archivo ELF
El archivo ELF contiene algunos metadatos para cada símbolo, lo que indica su visibilidad.
La forma más sencilla de observar esto es con el nm
herramienta.
Por ejemplo, en un hello world independiente de Linux x86_64 GAS:
red eléctrica
.text
.global _start
_start:
asm_main_after_prologue:
/* write */
mov $1, %rax /* syscall number */
mov $1, %rdi /* stdout */
lea msg(%rip), %rsi /* buffer */
mov $len, %rdx /* len */
syscall
/* exit */
mov $60, %rax /* syscall number */
mov $0, %rdi /* exit status */
syscall
msg:
.ascii "hellon"
len = . - msg
GitHub en sentido ascendente
compilar y ejecutar:
gcc -ffreestanding -static -nostdlib -o main.out main.S
./main.out
nm
da:
00000000006000ac T __bss_start
00000000006000ac T _edata
00000000006000b0 T _end
0000000000400078 T _start
0000000000400078 t asm_main_after_prologue
0000000000000006 a len
00000000004000a6 t msg
y man nm
nos dice que:
Si está en minúsculas, el símbolo suele ser local; si está en mayúsculas, el símbolo es global (externo).
entonces vemos eso _global
es visible externamente (mayúsculas T
), pero el msg
que no marcamos como .global
no es (minúscula t
).
El enlazador entonces sabe cómo explotar si se ven múltiples símbolos globales con el mismo nombre, o hacer cosas más inteligentes si se ven tipos de símbolos más exóticos.
Si no marcamos _start
como global, ld
se pone triste y dice:
no puedo encontrar el símbolo de entrada _start
Si haces scroll puedes encontrar los informes de otros programadores, tú de igual forma tienes la opción de mostrar el tuyo si te gusta.