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 :

Copier dans %rax le contenu des 8 octets de poids fort d'une zone de mémoire de 16 octets [Débutant(e)]


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Copier dans %rax le contenu des 8 octets de poids fort d'une zone de mémoire de 16 octets
    Bonjour à tous,

    Étant étudiant en DUT info, je dois apprendre l'assembleur.
    Le problème c'est que j'ai mal commencé puisque je ne comprends pas trop le main de ce programme :

    Consigne: on veut copier dans %rax le contenu des 8 octets de poids fort d'une zone de mémoire de 16 octets "var32" :

    Code : 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
           .data
     
    var32:
     
           .long 1
           .long 2
           .long 3
           .long 4
     
    chiffre:
     
           .byte 0
    .global main
    .text
     
    main:
           movq $var32, %rbx #On est d'accord qu'ici je copie l'adresse de $var32 dans %rbx ?
           movq 1(%rbx), %rax # Ici j'incrémente l'adresse mémoire que pointe %rbx de 1 pour récupérer les 8 octets suivants (les deux derniers long)
    Êtes-vous d'accord avec cela ?

    Merci d'avance et bonne journée

  2. #2
    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
    Il me semble que tu utilise le GNU assembleur , arg,il fait de la syntaxe AT&T de plus je n'ai jamais aimé cet assembleur
    (il a l'avantage d’être un assembleur multi-plateforme mais on général quand je peux m'en passer je le fait ).

    Je ne suis pas sur que l'opération movq est ce que tu recherche ? , il est utilisé pour le MMX ce n'est peut être pas l'idéal d'utiliser ce genre d'instruction quand on débute en assembleur.
    De plus j'ai lu que " L'instruction ne peut pas être utilisée pour transférer des données entre des emplacements de mémoire."

    Le premier me semble juste , le deuxième je pourrais pas dire.

    " Consigne: on veut copier dans %rax le contenu des 8 octets de poids fort d'une zone de mémoire de 16 octets "var32" : "
    Pour ma part si je devrait le faire j'utiliserai des instructions plus simple , comme le and , le or et les décalages de bit , mais peut être que le but de votre exo est d'utiliser spécialement les instructions MMX ?

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Oui j'utilise le GNU assembleur ^^
    Ouais je le trouve aussi complexe, sauf que je ne peux pas le comparer à d'autres et on nous oblige à rester dessus...

    Bah par le movq je cherche à déplacer l'adresse où se trouve $var32 dans registre rbx. On l'utilise toujours le mov{b, w, l, q} pour déplacer des adresses dans et entre des registres :c
    On n'a pas appris les AND, OR ...

  4. #4
    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
    ok , je retire je que j'ai dit mov{b, w, l, q} sont des registre correct x)

    Ok bon le or ,and me semble les b.a.ba comme instruction de base mais bon x)
    Et donc tu as appris au moins décalage de bit ?
    Pour moi si on veut prendre les bit de poids fort , il faut faire un decalage de bit vers la droite.

  5. #5
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 453
    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 453
    Points : 43 106
    Points
    43 106
    Par défaut
    Premier point, sais tu ce que veut dire bit de poids fort, bit de poids faible ? (en anglais MSB et LSB - Most Significative Bit, Less Significative Bit).

    Si tu ne le sais pas, les bits les plus à gauche sont les bits de poids fort ou bit plus significatif. On dit qu'Ils ont le plus de poids car :
    1000=0x1+0x2+0x4+1x8=8
    0100=0x1+0x2+1x4+0x8=4

    Plus les bits à gauche sont positionnées (càd mis à 1), plus le chiffre sera grand.

    Il te faut les 8 octets de poids forts donc les 32 bits les plus à gauche.

    Donc si tu charges l'adresse de 16 octets càd 64 bits dans un registre, il te faudra comme l'a dit Kannagi effectuer un décalage car avec les CPU Intel

    %ebx correspond aux 32 bits de poids faible du registre %rbx

    Et on ne peut pas accéder directement aux 32 bits de poids fort avec un pseudo-registre, il faut donc les faire .ressortir.

    Après, il y a peut-être plus simple. Les CPU Intel sont en Big endian c'est à dire qu'une adresse :
    0xA0B70708 sera stocké comme ceci en mémoire : 08 07 B7 A0
    https://fr.wikipedia.org/wiki/Little...#Little_endian

    Dans le cas de cette adresse 32 bits,je peux lire les 16 bits de poids fort comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    xor eax,eax
    mov $adr+2,%ax
    Je charge donc les 16 bits de poids fort de mon adresse 32 bits dans le pseudo-registre 16 bits ax correspondant aux 16 bits de poids faible du registre 32 bits eax. Le xor eax,eax étaént là pour mettre le registre eax à 0 avant chargement (équivalent plus rapide de movl $0,%eax)

    On n'a pas appris les AND, OR ...
    Tu n'as pas eu de cours de logique ? voici une introduction

    en gros un OR correspond à un + et un AND à un x

    exemple en binaire :

    0+0=0, 0+1=1, 0 or 0=0, 0 or 1=1 cela permet de forcer des bits à 1
    0x0=0, 0x1=0, 1x1=1 0 and 0=0, 0 and 1=0, 1 and 1=1, cela permet de masquer des bits (c'est à dire les forcer à 0). C'est beaucoup utilisé en assembleur.
    Je t'invites à consulter ceci :
    https://fr.wikipedia.org/wiki/Table_de_v%C3%A9rit%C3%A9

    Mais tu n'en a pas besoin pour ce cas.
    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

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Kannagi >> Non je n'ai pas appris les décalages de bits, ou du moins, je ne sais pas ce que c'est. J'ai regardé à l'instant ce que c'était avec une petite recherche et... comment dire que j'y comprends pas grand chose ? ^^
    Tu parles bien de ça :

    RCL registre, 1 (Rotate Carry Left) : Effectue une rotation des bits sur la gauche en passant par l'indicateur de retenue CF. Le contenu de CF est introduit à droite, puis le bit de poids fort est copié dans CF.
    RCR registre, 1 (Rotate Carry Right) : Effectue une rotation des bits sur la droite en passant par l'indicateur de retenue CF. Le contenu de CF est introduit à gauche, puis le bit de poids faible est copié dans CF.
    ROL registre, 1 (Rotate Left) : Effectue une rotation des bits sur la gauche. Le bit de poids fort est copié dans CF et réintroduit à droite.
    ROR registre, 1 (Rotate Right) : Effectue une rotation des bits sur la droite. Le bit de poids faible est copié dans CF et réintroduit à gauche.
    SHL registre, 1 (Shift Left) : Décale les bits du registre indiqué de 1 bit vers la gauche. (Les bits sortants sont transférés dans l'indicateur de retenue CF mais ne sont pas réintroduits à droite).
    SHR registre, 1 (Shift Right) : Décale les bits du registre indiqué de 1 bit vers la droite. (Les bits sortants sont transférés dans l'indicateur de retenue CF mais ne sont pas réintroduits à gauche).
    chrtophe >> Avec ton message tu m'as fait comprendre un truc dont j'avais pas du tout fait gaffe !
    Pourquoi utiliser des mov/ lorsqu'on peut tout simplement prendre des octets de poids forts/faibles en prenant le registre que contient le registre où j'ai mis l'adresse

    En gros, si je fais un :
    movq $var32, %rax# Je passe l'adresse de $var32 dans le registre rax qui fait 64 bits donc juste assez pour recevoir $var32 ?
    movq (%eax), %rbx #Je passe la valeur du registre %eax qui contient les 32octets de poids fort dans %rbx ?

    Pour ce qui est des AND et des OR, j'ai compris ça en mathématiques (ça ressemble plus à des implications, etc...)
    Mais "forcer les bits à 1" ou les forcer à 0 j'ai pas bien pigé ^^


    Merci beaucoup pour votre aide!

  7. #7
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 453
    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 453
    Points : 43 106
    Points
    43 106
    Par défaut
    Non je n'ai pas appris les décalages de bits, ou du moins, je ne sais pas ce que c'est.
    Comme le nom l'indique tu décales tes bits vers la droite ou la gauche
    exemple :
    00001001 si tu décale d'un bit vers la droite, tu auras : 00000100, il y a donc perte d'information, tu perd le bit de poids faible, idem pour le décalage à gauche, tu perdras alors le bit de poids fort.

    Ceci a également une très importante et très intéressante propriété : décaler une valeur d'un bit vers la droite revient à faire une division par 2, de 2 bits vers la droite une division par 4, etc... , et inversement le décalage vers la gauche fera une multiplication. Cela n'est valable que pour les valeurs paires.

    Dans mon exemple : 1001 en binaire est égal à 9 en décimal , 100 en binaire est égal à 4 en décimal.
    9/2 donne bien 4 en division en nombres non décimaux. Cette méthode te fait perdre le reste.

    Cela revient mathématiquement à faire 2 multiplié ou divisé par puissance nombre de bits de décalage. cela fait partie de l’algèbre de Boole.

    Mais "forcer les bits à 1" ou les forcer à 0 j'ai pas bien pigé ^^
    Je t'es expliqué comment forcer un bit à 0 ou à 1.

    Ce qu'il faut comprendre, c'est que le langage assembleur est proche de l'électronique. Un circuit intégré attend des informations sur des pattes. Ces informations sont soit du courant (1) ou pas de courant (0). Ces circuits dialoguent avec son environnement via des registres attendant des infos ou en donnant ou les deux. Forcer un bit bine précis à 1 ou 0 permet donc d'envoyer une info.
    Exemple :
    sur un processeur x86, l'activation à 1 du bit 0 (donc le bit de poids le plus faible) du registre cr0 du CPU va passer celui-ci en mode protégé. Les autres bits ayant des significations autres, il ne faut pas les toucher , on va donc forcer ce bit à 1 avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ; code en notation intel
    mov eax,cr0
    or eax,1
    mov cr0,eax
     
    ; code en notation At&T (susceptible d'être erroné je connais mal cette syntaxe)
    mov cr0,%eax
    or %eax,1
    mov %eax,cr0
    info complémentaire : Ceci ne suffit pas, il faut avant préparer des structures en mémoire, mais c'est un autre sujet
    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

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup de ton aide!

    Comment fais tu le décalage vers le gauche ou vers la droite?

    Pour ce qui est des forçages de bits à 0 ou à 1, ça me paraît d'être un niveau assez confirmé ...
    Parce qu'en fait je ne sais pas du tout qui sont les registres qui attendant des informations d'un seul bit (0 ou 1, il prend donc qu'un seul bit ?)
    " l'activation à 1 du bit 0 (donc le bit de poids le plus faible) du registre cr0 du CPU va passer celui-ci en mode protégé"
    >> cr0 est donc un registre qui ne prend qu'un bit ?

    Par rapport à ce que j'ai compris plus haut, peux tu me confirmer que j'ai bon ?

    movq $var32, %rax# Je passe l'adresse de $var32 dans le registre rax qui fait 64 bits donc juste assez pour recevoir $var32 ?
    movq (%eax), %rbx #Je passe la valeur du registre %eax qui contient les 32octets de poids fort dans %rbx ?

    Merci beaucoup de tes explications!

  9. #9
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 453
    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 453
    Points : 43 106
    Points
    43 106
    Par défaut
    Les opcodes de décalage de bits sur x86 sont SHL et SHR (shift left et right)

    Ceci signifie que tu vas charger 8 octets dans rax depuis l'adresse $var32, $var32 étant une adresse 64 bits (8x8=64 bits) si ton segment de code est 64 bits.
    q signifie quad car en fait on transfère 4 mots machine, un mot machine valant 16 bits (4x16=64 bits), voila l'explication te permettant peut-être de mieux mémoriser.
    b=byte, w=word, l=long,q=quad

    En général, un registre contient plusieurs bits, pour le CPU X86 c'est 32 ou 64 bits. Sauf :

    les registres de segments (CS,DS, ES, FS, GS) et TR qui eux seront toujours 16 bits
    Les registres commandes (cr0 à cr3) et debug (dr0 à 4) toujours 32 bits, du moins de ce que j'en sais

    Pour les registres spécifiques aux circuits intégrés pilotant des périphériques par exemple, cela dépend de ceux-ci, il faut voir la documentation, mais ça c'est quand tu fais de l’électronique ou de la programmation de drivers. Sur les ordis, ces registres peuvent aussi être exposés à une adresse mémoire particulière. Il ne faut pas dans ce cas voir la valeur globale contenu dans ce registre mais plutôt le positionnement d'un bit à 1 ou 0 à une position précise (bit 3, bit 7, etc.). Il se peut que ce registre contienne une valeur numérique communiqué au périphérique ou par le périphérique, dans ce cas on prend la valeur globale. C'est un peu comme une suite d'octets en mémoire, ils peuvent contenir une ou plusieurs commandes au processeur si il s'agit de code, ou une valeur numérique pouvant représenter un nombre, un caractère ou une adresse mémoire.

    Avec tout ça, tu as quelques cours d'avance. Tu ne verras peut-être pas ces notions si tu ne fait que survoler l'assembleur. Donc ne te focalises pas sur tout ceci qui ne sera peut-être pas à ton programme. Ca ne te sera pas forcément inutile.

    Tout ça se relie comme ceci :
    - Mathématiques : algèbre de Boole et de façon plus abtraite théorie des ensembles
    - Electricité/electronique numérique : pouvant se présenter sous la dénomination de logique combinatoire
    - Programmation bas niveau : assembleur, langage machine.
    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

  10. #10
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Bonjour,


    Ok mais moi ce que je voulais faire c'était de stocker var32 dans un registre puis récupérer les 64 bits de poids fort... hors je ne connais pas de registre 128 bits existant sur du x84 ... x) Effectivement là c'est vraiment du haut niveau x)

    Merci pour les cours d'avance ^^

    Bonne journée à tous et merci des réponses!

Discussions similaires

  1. Comment avoir l'octet de poids fort et faible d'un nombre
    Par azerty25 dans le forum Général Python
    Réponses: 7
    Dernier message: 02/12/2015, 16h41
  2. [DOM] Copier le contenu des fichiers XML d'un meme rep dans un seul fichier XML !
    Par amo-said dans le forum Bibliothèques et frameworks
    Réponses: 6
    Dernier message: 20/05/2011, 18h18
  3. Réponses: 0
    Dernier message: 20/05/2011, 16h48
  4. Réponses: 1
    Dernier message: 21/10/2010, 15h46
  5. [HTML] affichage du contenu des balises 'alt' dans une iframe
    Par etarip dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 11/08/2005, 14h08

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