web-dev-qa-db-fra.com

Qu'est-ce que global _start en langage d'assemblage?

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
21
vikkyhacks

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
30
Sedat Kapanoglu

_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:
...
2
old_timer

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.

0
Moksh