Ceci est mon code de niveau d'assemblage ...
section .text
global _start
_start: mov eax, 4
mov ebx, 1
mov ecx, mesg
mov edx, size
int 0x80
exit: mov eax, 1
int 0x80
section .data
mesg db 'KingKong',0xa
size equ $-mesg
Sortie:
root@bt:~/Arena# nasm -f elf a.asm -o a.o
root@bt:~/Arena# ld -o out a.o
root@bt:~/Arena# ./out
KingKong
Ma question est À quoi sert le _start global ? J'ai tenté ma chance avec Mr.Google et j'ai découvert que c'est utilisé pour indiquer le point de départ de mon programme. Pourquoi ne pouvons-nous pas simplement avoir le _start
pour indiquer le début du programme, comme celui présenté ci-dessous, qui produit un avertissement un peu
section .text
_start: mov eax, 4
mov ebx, 1
mov ecx, mesg
mov edx, size
int 0x80
exit: mov eax, 1
int 0x80
section .data
mesg db 'KingKong',0xa
size equ $-mesg
root@bt:~/Arena# nasm -f elf a.asm
root@bt:~/Arena# ld -e _start -o out a.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048080
root@bt:~/Arena# ld -o out a.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048080
La directive global
est spécifique à NASM. C'est pour exporter des symboles dans votre code là où il pointe dans le code d'objet généré. Ici, vous marquez _start
symbole global afin que son nom soit ajouté dans le code de l'objet (a.o
). L'éditeur de liens (ld
) peut lire ce symbole dans le code de l'objet et sa valeur afin de savoir où marquer en tant que point d'entrée dans l'exécutable en sortie. Lorsque vous exécutez le fichier exécutable, il commence à l'endroit indiqué par _start
dans le code.
Si une directive global
manque pour un symbole, ce symbole ne sera pas placé dans la table d'exportation du code objet, de sorte que l'éditeur de liens n'a aucun moyen de connaître le symbole.
Si vous souhaitez utiliser un nom de point d'entrée différent de _start
(qui est le nom par défaut), vous pouvez spécifier le paramètre -e
à ld comme suit:
ld -e my_entry_point -o out a.o
_start
est défini par le script de l'éditeur de liens ld
par défaut
ld -verbose a.o | grep ENTRY
les sorties:
ENTRY(_start)
Le format de fichier ELF (et tout autre format d’objet, je suppose), indique explicitement à quelle adresse le programme commencera à s’exécuter via le champ d’en-tête e_entry
.
ENTRY(_start)
indique à l'éditeur de liens de définir pour cette entrée l'adresse du symbole _start
lors de la génération du fichier ELF à partir de fichiers objets.
Ensuite, lorsque le système d'exploitation commence à exécuter le programme ( exec
appel système sous Linux), il analyse le fichier ELF, charge le code exécutable en mémoire et définit le pointeur d'instruction sur l'adresse spécifiée.
Le drapeau -e
mentionné par Sedat remplace le symbole _start
par défaut.
Vous pouvez également remplacer l'intégralité du script de l'éditeur de liens par défaut par l'option -T <script>
, voici un exemple concret qui permet de configurer des éléments d'assemblage nus .
Une étiquette n'est pas explicitement globale tant que vous ne l'avez pas déclarée globale. Vous devez donc utiliser la directive globale.
L'étiquette globale "_start" est nécessaire pour l'éditeur de liens. S'il n'y a pas d'adresse globale _start, l'éditeur de liens se plaindra car il ne peut en trouver aucune. Vous n'avez pas déclaré _start en tant que variable globale, de sorte qu'il ne soit pas visible en dehors de ce module/objet de code et donc non visible pour l'éditeur de liens.
C’est le contraire de C où les choses sont supposées être globales à moins que vous ne les déclariez locales.
unsigned int hello;
int fun ( int a )
{
return(a+1);
}
bonjour et amusement sont globaux, visibles à l'extérieur de l'objet, mais ceci
static unsigned int hello;
static int fun ( int a )
{
return(a+1);
}
les rend local non visible.
tous locaux:
_start:
hello:
fun:
more_fun:
ceux-ci sont maintenant disponibles pour l'éditeur de liens et d'autres objets
global _start
_start:
global hello
hello:
...
global _start
est simplement une étiquette qui pointe vers une adresse de mémoire. Dans le cas de _start, s’agissant des fichiers binaires ELF, c’est l’étiquette par défaut utilisée qui sert d’adresse de démarrage du programme.
main
ou _main
ou main_
est également connu du langage C et est appelé par "code de démarrage" qui est "généralement" lié à - si vous utilisez C.
J'espère que cela t'aides.