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 :

Apprendre l'assembleur x86


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2008
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 623
    Points : 1 370
    Points
    1 370
    Par défaut Apprendre l'assembleur x86
    Bonjour à tous,

    Je souhaiterai me mettre à l'assembleur, uniquement dans un but d'apprentissage (en tout cas pour le moment).
    J'ai un peu regardé le forum et les tutos et quelques questions me viennent à l'esprit.

    Quel est l'assembleur le plus abordable/intéressant/le plus utilisé à apprendre pour l'environnement Windows ? J'entends parler de Intel, AT&T, de NASM, FASM, MASM...
    Connaissez-vous des tutos intéressant à ce sujet?

    Merci par avance.

  2. #2
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Bonjour,

    Je dirais que peu importe le compilateur, l'assembleur x86 reste le même (attention avec AT&T quand même )
    Comme tu le dis tu cherches des tutos, il doit y en avoir pas mal en Français qui sont compilés avec MASM,
    Sinon, si l'anglais ne te fait pas peur, tu peux foncer vers FASM

  3. #3
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2008
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 623
    Points : 1 370
    Points
    1 370
    Par défaut
    Merci Forthman.

    J'ai lu ça sur Wikipédia :

    MASM supporte une grande variété de macros aidant à la programmation en langage assembleur ainsi que des idiomes de programmation structurée, incluant des constructions de haut niveau pour les boucles, les appels de procédures, les branchements, etc. ce qui fait de MASM un assembleur à programmation de haut niveau
    Comme je me lance dans cette aventure uniquement dans le but d'apprendre ce qu'est la programmation bas niveau, est-ce que MASM est un bon choix?
    Que pense-tu de NASM? Le tutoriel sur développez semble très bon.

  4. #4
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Si tu veux te concentrer sur le fonctionnement du processeur, peu importe le compilo car tu ne te servira pas des fonctions avancées.
    donc comme Nasm Tasm Masm Fasm utilisent tous la syntaxe intel et non AT&T ce n'est pas un problème.

    Pour ma part j'utilise Fasm car il est plus bas niveau que les autres (ce n'est que mon avis), et qu'il se télécharge
    de manière toute à fait légale sur le site officiel
    Seul reproche que je peux faire à Fasm, c'est de ne pas avoir d'IDE pour Linux, alors que j'adore la simplicité
    de l'IDE pour windows (avec possibilité de tester directement le programme avec la touche F9)

  5. #5
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2008
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 623
    Points : 1 370
    Points
    1 370
    Par défaut
    Ok, dommage qu'il n'y ai pas de doc en français sur FASM. Je peux me débrouiller avec l'anglais mais, l'assembleur est déjà suffisament complexe pour que j'ajoute une difficulté supplémentaire.

    J'ai commencé le tuto http://esauvage.developpez.com/tutor...tel-avec-nasm/, mais j'ai toujours du mal à comprendre ce qu'est un registre...

    Par exemple dans le I.5, il y a :

    Code assembleur : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    org 0x0100 ; Adresse de début .COM
    ;Ecriture de la chaîne hello dans la console
    mov dx, hello
    mov ah, 0x9
    int 0x21
    ret
    hello: db 'Bonjour papi.', 10, 13, '$'

    Plus bas :

    int 0x21 (ne marche que sous DOS)
    Ce programme fait des choses différentes selon la valeur stockée dans le registre AH. Si AH vaut 9, alors ce programme affiche la chaîne de caractères dont l'adresse du début est stockée dans DX. Voilà pourquoi on a mis l'adresse de notre chaîne de caractères dans DX, et 9 dans AH.
    Bon je me doutait que l'assembleur était compliqué, mais à ce point là

  6. #6
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Un registre c'est simple c'est une mémoire dans le processeur , par exemple AH est un registre (de 1 octet).
    int 21 est une interruption dos ,on peut le comparé avec une fonction , cette 'fonction' attend 2 argument le premier dans le registre ah et un autre dans dx.
    Pour écrire a écran il faut son adresse (que tu donne dans dx) et le 'type' de la fonction ici c'est faire un 'printf' donc ah = 9 , mais faut pas être devin il y a des documentations sur le net sur l'interruption 21.

    Voici un lien trouver vite fait sur int 21 : http://stanislavs.org/helppc/int_21.html

  7. #7
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    oui, il y a les interruptions logicielles, et matérielles.

    Les logicielles sont un moyen simple d'appeler une routine, sans avoir besoin de connaître son emplacement mémoire.
    le mot "interruption" peut porter à confusion, car dans ce cas, le programme n'est pas vraiment interrompu (c'est juste que le codage
    est similaire à une interruption matérielle)

    les interruptions matérielles sont déclenchées par... le matériel
    le clavier, la souris, les timers...etc...

    avec l'interruption 21h (dos) la fonction est transmise par le registre AH. ce n'est pas imposé par la machine, mais par Microsofth qui a décidé la chose.
    tout comme toi, tu peux décider après un saut vers un sous programme, d'effectuer une opération différente suivant le contenu d'un registre particulier.

    L'assembleur n'est pas compliqué en soit, les fonctions de bases sont simples et peu nombreuses. Par contre c'est l'assemblage de toutes ces fonctions, ainsi
    que l'approche très différente par rapport à un langage évolué qui font qu'à la fin... c'est moins clair

  8. #8
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2008
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 623
    Points : 1 370
    Points
    1 370
    Par défaut
    Ok, je comprends un peu mieux.
    L'interruption a besoin de paramètres pour faire son travail et elle sait où les trouver.

    En gros (très gros), le code :

    Code assembleur : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    org 0x0100
    mov dx, hello
    mov ah, 0x9
    int 0x21
    ret
    hello: db 'Bonjour papi.', 10, 13, '$'

    Pourrait être traduit en langage haut niveau de la façon suivante :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var hello = "Bonjour papi";
     
    var fonction = "afficher";
    var chaine = hello;
     
    interruption(fonction, chaine);

    Une question, comment se fait-il qu'il est possible d'utiliser le contenu de "hello" avant sa définition ?
    La lecture du programme ne se fait pas de haut en bas?

  9. #9
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    l'assembleur (le logiciel qui assemble le programme) est multi-passes donc les données peuvent être définies avant/après sans importance.

  10. #10
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    C'est un peu ça effectivement.
    Mais hello: ce n'est pas une adresse mémoire (dans la RAM) donc inutile de le définir comme en C , de plus en C il le demande de le définir parce que avant son appellation il ne sait pas ce que c'est , en asm c'est différent hello: est une adresse (il sait deja ce que c'est) , tu peux écrire en 'dur' mais la faudra compter le nombre instruction (et leur taille) pour savoir ou se trouve les donnés.

  11. #11
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Je dirais plutôt que l'assembleur ne s'occupe pas de la taille ou du type de données, c'est au programmeur de le faire.

    Par exemple, tu peux très bien définir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    hello: db 'Bonjour papi.', 10, 13, '$"
    et faire plus loin dans ton programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    mov bx,hello
    inc byte [bx]
    ce qui aura pour conséquence d'ajouter 1 au premier octet de cette chaine qui deviendra "Conjour papi"

  12. #12
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2008
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Janvier 2008
    Messages : 623
    Points : 1 370
    Points
    1 370
    Par défaut
    Citation Envoyé par Kannagi Voir le message
    C'est un peu ça effectivement.
    Mais hello: ce n'est pas une adresse mémoire (dans la RAM) donc inutile de le définir comme en C , de plus en C il le demande de le définir parce que avant son appellation il ne sait pas ce que c'est , en asm c'est différent hello: est une adresse (il sait deja ce que c'est) , tu peux écrire en 'dur' mais la faudra compter le nombre instruction (et leur taille) pour savoir ou se trouve les donnés.
    Je ne comprends pas pour hello. Si ce n'est pas une adresse mémoire dans la RAM, c'est qu'elle est dans le processeur?

    Je suis passé à ce tuto : http://benoit-m.developpez.com/assem...riel/index.php, je pense qu'il explique des concepts qui me seront indispensable pour bien comprendre l'assembleur.

    Par contre je ne comprends pas cette phrase :

    Votre PC est conçu pour gérer 1 Mo (soit 220 octets) de mémoire vive en mode réel. Il faut donc 20 bits au minimum pour adresser toute la mémoire. Or en mode réel les bus d'adresses n'ont que 16 bits. Ils permettent donc d'adresser 216 = 65536 octets = 64 Ko, ce qui est insuffisant !
    1Mo = 220 octets ? même si c'est 1MBits, je comprends pas le résultat
    16 bits pour adresser 65536 octets OK
    65536 octets = 216 quoi ?

    Si quelqu'un peut m'éclairer, ça serai sympa.




    Edit : en relisant mon message, j'ai compris à quoi ça correspond : 216 -> 2^16 et pareil pour 220.

  13. #13
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Je ne comprends pas pour hello. Si ce n'est pas une adresse mémoire dans la RAM, c'est qu'elle est dans le processeur?
    Pour ça que je trouve le x86 pas évident , on comprend (de mon point de vue) plus facilement l'assembleur avec un processeur plus simple.

    hello: est l'adresse ou se trouve ta chaine dans ton exécutable , pour ça que je conseille de toujours regardé un peu les opcode pour qu'on puisse bien comprendre comment ça marche derrière (surtout avec un COM qui possède pas grand chose donc facile de voir les opcode).
    Pour envoyer une valeur en mémoire il faut utiliser MOV Registre général, Mémoire, qui envoie une valeur de ton registre en mémoire , et la oui tu envoie en Mémoire une variable que tu pourra récupérer, en assembleur c'est toi qui choisit ou tu écris en mémoire (enfin pas exactement c'est OS qui le décide , mais dans le .com les adresse sont pas réel il me semble).

  14. #14
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 446
    Points : 43 088
    Points
    43 088
    Par défaut
    Pour essayer de résumer de façon très simple ce que fait un processeur.

    - Il lit ou écrit des données à des adresses, pour cela il passe par des registres qui sont des cases internes à lui.
    - il fait des calculs tels qu'additions, soustractions entre registres, entre un registre et une adresse mémoire, entre deux adresses mémoires, cela dépend des capacités des processeurs.
    - il fait des sauts à des adresses selon des critères en utilisant des flags stockés dans un registre dédié au flag ( exemple flag 0, flag négatif,flag overflow)
    - il va traiter les interruptions : Quand il reçoit une interruption, il va arrêter ce qu'il fait et sauter à l'adresse du code de l'interruption stocké dans la table des interruptions)

    Tout cela se fait par suite d'instructions, un peu comme dans ton code C, tu as plusieurs lignes, chaque ligne fait une petite chose de ton programme. Ta ligne C correspond a une ou (souvent) plusieurs instructions assembleur.

    Ceci est aussi bien valable pour un processeur x86, un PowerPC, ou le processeur de ta machine à laver. Ce qui diffère, c'est le nombre de registres, leur taille (8,16,32,64 bits, ou moins pour l'exemple du CPU de ta machine à laver), la taille des bus de données et d'adresses, leur nombre d'instructions par secondes. Autre exemple, un processeur RISC n'a pas d'instruction pour effectuer une division (mais on peut diviser avec), le processeur 8086, l’ancêtre de la gamme x86 n'a pas d'instructions pour gérer les calculs avec des nombres réels ni de fonctions de trigonométrie par exemple. Pour celles-ci, il fallait ajouter un coprocesseur mathématique, ou l'émuler. dans le cas du x86, Le processeur arithmétique a été intégré dans le CPU depuis le 80486 ( modèle avant le Pentium).

    Avoir des notions d'électronique voire d'électrotechnique peuvent permettre de mieux comprendre tout cela. Un CPU, ce n'est que des portes logiques et c'est très con, ça ne connait que 0 ou 1 : le courant passe ou ne passe pas. Une adresse mémoire sur 16 bits correspond en fait à un bus : un ensemble de 16 fils. faire passer ou non du courant des ces fils permet de créer une adresse ou une données : exemple fil 1 et 2 allumés donneront : 1100000000000000 soit 0xc000 den héxadécimal ou 49152 en décimal

    Le cas de la segmentation n'est pas facile à comprendre. Cela vient de l'évolution de la gamme des processeurs Intel. Les 1er CPU ne pouvait gérer que 64 K de RAM. CPU 16 bits adresse de 0 à 1111111111111111 ou 0 à FFFF.

    pour dépasser la taille d'adresse de FFFF, une ruse à été utilisé : la segmentation. L'adresse était présenté en 2 morceaux : le segment et l'offset, l'offset représentant le décalage par rapport au segment.
    exemple l'adresse de démarrage du chargement d'un système :
    0000:7c00 peut être exprimé en 07c0:0000 : les 2 notations pointent sur la même adresse.
    A l'arrivée du mode protégé, les choses ont changé, tant que tu es en mode réel : aucun changement en mode protégé les segments permettent de restreindre l'accès aux adresses. Cette situation de segment est ensuite devenu obsolète avec l'évolution des système de pagination dans le x86. La segmentation n'est donc plus trop utilisé. Par contre, les CPUs intel démarrent toujours en mode réel, avant de passer en mode protégé , il faut créer une table de segmentation de base, une fois en mode protégé, on crée une table de segmentation si on souhaite utiliser celle-ci, puis on active celle-ci. Je ne sais pas si d'autres CPU que le gamme x86 utilise la segmentation (probablement)

    On ne programme quasiment plus en assembleur. L'utilité actuelle de programmer en assembleur, c'est pour piloter des microcontroleurs (et encore) qui sont en fait des CPU embarquant de la RAM, de la ROM.

    Par contre ça à un réel intérêt pour comprendre le cœur d'un ordinateur.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  15. #15
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Citation Envoyé par Kannagi Voir le message
    Pour envoyer une valeur en mémoire il faut utiliser MOV Registre général, Mémoire, qui envoie une valeur de ton registre en mémoire , et la oui tu envoie en Mémoire une variable que tu pourra récupérer.
    Vrai pour l'AT&T mais pas pour la syntaxe INTEL

    chez intel c'est "mov destination,source"

Discussions similaires

  1. Apprendre l'Assembleur : par où commencer ?
    Par Arch Enemy dans le forum Assembleur
    Réponses: 16
    Dernier message: 26/11/2020, 08h38
  2. Apprendre l'Assembleur (questions)
    Par Johannliebert dans le forum Assembleur
    Réponses: 3
    Dernier message: 30/05/2007, 10h14
  3. Tutoriel pour apprendre l'Assembleur
    Par Bad_Day dans le forum Assembleur
    Réponses: 4
    Dernier message: 11/02/2007, 16h34
  4. integrer du code Assembleur (x86) dans python
    Par nephhh dans le forum Général Python
    Réponses: 2
    Dernier message: 11/02/2007, 11h50
  5. Conversion instructions assembleur X86 -> PPC
    Par bencall dans le forum Assembleur
    Réponses: 4
    Dernier message: 28/09/2006, 22h02

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