IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 32-bits / 64-bits Assembleur Discussion :

"attempt to define a local label before any non-local labels" + questions


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Candidat au Club
    Homme Profil pro
    Autre
    Inscrit en
    Décembre 2012
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Décembre 2012
    Messages : 1
    Points : 2
    Points
    2
    Par défaut "attempt to define a local label before any non-local labels" + questions
    Salut tout le monde, je poste mon premier sujet ici pour demander votre aide, en effet je commence l'assembleur sur Linux mais dès le premier programme j'ai une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    "test.asm:2: error: attempt to define a local label before any non-local labels"
    C'est la ligne du .data mais pourtant c'est bien ça non pour dire qu'on initialise des variables ?

    Mon code source :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ; programme inutile pour apprendre l'assembleur 
    .data
    test: db 5
    testt: dw 1
     
    .bss 
    resword: resw 1; reserve 1 mot pour plus tard
     
    .text
    mov eax, 10 ; 10 dans le registre eax
    add eax, 15 ; on fait 10 + 15 dans eax

    Et je compile en faisant : "nasm -f elf test.asm"



    Voilà, et j'aimerais aussi savoir, quand on programme sous DOS c'est sous n'importe quel OS alors ? Et comment faire ça et à quoi ça sert ?



    Merci d'avance et désolé je débute en Assembleur j'ai un peu de mal



    EDIT : Résolu, en fait fallait juste rajouter des "section" pour ".data" etc

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 368
    Points : 23 622
    Points
    23 622
    Par défaut
    Bonjour et bienvenue.

    Non, ce n'est pas tout-à-fait la même chose. Les formats de fichiers exécutables du monde sont « a.out », « COFF » et « ELF », ce dernier étant en vigueur depuis SVR4, donc autant dire que c'est lui qui est réellement le format d'exécution officiel sous Unix aujourd'hui.

    Ces trois formats d'exécutable, en revanche, contiennent par définition plusieurs sections telles que « .text », « .data », « .rodata » ou « .bss ». Elles sont nécessaires pour isoler les différentes parties d'un programme, en l'occurrence (et respectivement) le code exécutable compilé, les données spécifiées dans le code, les données réputées en lecture seule (par exemple une chaîne de caractère passée entre guillemets) et les données nécessaires à l'initialisation de certains objets comme les variables globales.

    Ça veut dire que ces sections sont inhérentes au format de fichier exécutable que tu utilises et qu'elles seront donc générées à la compilation, quel que soit le contenu de ton fichier source.

    En outre, dans le monde PC et Microsoft, D.O.S. avait initialement son propre format d'exécutable « MZ » utilisé dans les fichiers *.exe. Avec l'apparition de Windows, ce format a d'abord été étendu en « NE » (New Executable) puis rapidement en « PE » pour « Portable Executable », toujours en vigueur. Or, « PE » est réputé dériver de COFF. Donc, tu vas retrouver les sections décrites ci-dessus à peu près partout. Ça donne l'impression qu'ils s'agit de fondamentaux de la programmation bas niveau, mais ce n'est qu'un concours de circonstances.

    Par contre, comme on l'a dit, ces sections seront générées dans le fichier exécutable, si elles sont nécessaires, par l'éditeur de liens et en fonction des informations à transmettre. Par contre, le nombre de sections n'est pas limité et tu peux éventuellement ajouter les tiennes si cela a un intérêt (c'est utile, par exemple, pour ajouter une icône à un fichier exécutable sous Windows). Il existe donc une directive en assembleur pour les déclarer mais il est très peu probable que tu en aies besoin lors de l'écriture de tes premiers programmes en assembleur.

    La notation pointée utilisée par NASM pour ses étiquettes, label en anglais, elle, n'a rien à voir avec les sections d'un fichier exécutable. Elle sert à définir des « étiquettes locales ». Une étiquette placée devant une instruction sert à automatiquement assigner à son symbole l'adresse de cette instruction, de manière à pouvoir y faire un saut ou y accéder en lecture/écriture. Lorsque tu utilises une étiquette locale (débutant par un point) , celle-ci n'est valide qu'entre deux étiquettes globales ordinaires. C'est utile lorsque tu fais beaucoup de boucles successives ou que tu répètes le même bloc de code. Ça te permet d'éviter d'avoir à définir une étiquette différente pour chaque bloc, étiquette qui serait inutilement visible par le programme entier. Exemple :

    Code ASM : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ; Efface le tableau numéro 1
    clrtab1:    mov di,tableau1
                xor ax,ax
                mov cx,10 ; Dix éléments à effacer
    .pasfini:   stosw
                loop pasfini
     
    ; Efface le tableau numéro 2
    clrtab2:    mov di,tableau2
                xor ax,ax
                mov cx,16 ; Seize éléments à effacer
    .pasfini:   stosw
                loop pasfini
     
    ; Incrémente les éléments du tableau 3
     
    inctab3:    mov di,tableau3
                mov cx,13 ; Treize éléments à incrémenter
    .pasfini:   inc es:[si]
                dec cx
                jnz pasfini

    En revanche, ce qui était fréquent sous DOS, c'est la déclaration de plusieurs segments dans ton programme. Mais ça, c'est une caractéristique de l'Intel x86 en particulier (et ses compatibles, bien sûr) et en mode 16 bits uniquement, puisque c'est dans ce mode que DOS a été écrit et était exploité. Le 8086 associe tous les registres d'index avec des registres de segment CS, DS, ES, etc. qui permettaient en gros de déplacer une fenêtre exploitable de 64 Ko dans toute la mémoire disponible avec une granularité de 16 octets. « CS » signifiait « Code Segment » et était automatiquement associé à IP, le pointeur de programme, pour lire les instructions à exécuter. Et quand celles-ci faisaient des accès mémoire en passant un offset, celui-ci était implicitement associé à « DS » (Data Segment).

    Dans la mesure, donc, où plusieurs segments pouvaient être définis et où, dans certains cas, c'était le programme lui-même qui devait les initialiser, alors MASM reconnaissait la directive « SEGMENT », qui permettait de définir littéralement différentes sections dans un programme, au moins sur la forme. On utilisait conjointement « ASSUME » pour indiquer au compilateurs quelles sections étaient pointées par quels registres de segments à certains endroits du programme.

    Ces différents « segments » définis dans un programme correspondaient donc littéralement à des sections, et c'est comme cela qu'ils étaient traduits par l'éditeur de liens… pour autant que le format de destination les prenne en charge ! Si tu produisais un programme *.COM, le fichier ne contenait aucune méta-information.

    NASM, aujourd'hui, reconnaît les directives « SECTION » et « SEGMENT », et les considère comme exactement synonymes : http://www.nasm.us/doc/nasmdoc6.html

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 04/06/2009, 11h31
  2. Envoyer du courrier en non-local avec Postfix
    Par soumou dans le forum Réseau
    Réponses: 2
    Dernier message: 12/03/2006, 23h06
  3. Connexion sur une base Mysql distante (non locale)
    Par externa dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 20/02/2006, 11h34
  4. Connection non local
    Par smtjv dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 12/12/2005, 14h24
  5. [Label] Comment faire clignoter un label ?
    Par delphicrous dans le forum Composants VCL
    Réponses: 7
    Dernier message: 09/07/2004, 16h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo