2009-08-18 4 views
6

Considérez ce code assembleur x86:Déréférencer une étiquette dans l'assemblage x86

section .data 

foo: 
    mov ebx, [boo] 
    mov [goo], ebx 
goo: 
    mov eax, 2 
    mov eax, 3 
    ret 
boo: 
    mov eax, 4 
    mov eax, 5 
    ret 

Qu'est-ce qui se passe ici exactement? Lorsque je déréférence [boo] et mov à [goo] quoi exactement je me déplace là-bas? Juste une commande? Le ret aussi bien?


des questions de suivi:

  1. Est-ce déréférencement une étiquette me donner une adresse? Ou le code machine pour la première commande de l'étiquette?
  2. S'il s'agit d'un code machine, comment peut-il y avoir plus d'une commande? Toutes les commandes ne sont-elles pas essentiellement 32 bits (même si tous les bits ne sont pas utilisés)?
  3. Ligne de bas - est-ce que eax aura une valeur de 3 ou 5 à la fin?

Répondre

9

boo est le décalage de l'instruction mov eax, 3 à l'intérieur de la section .data. mov ebx, [boo] signifie "récupérer quatre octets au décalage indiqué par boo à l'intérieur de ebx". De même, mov [goo], ebx déplacerait le contenu de ebx au décalage indiqué par goo.

Cependant, le code est souvent en lecture seule, il n'est donc pas surprenant de voir le code se bloquer.

Voici comment les instructions à boo sont codées:

boo: 
b8 03 00 00 00   mov eax,0x3 
c3      ret 

Alors ce que vous obtenez en ebx est en fait 4/5 de l'instruction mov eax, 3.

+1

Il semble que cela se produit au travail parce qu'ils ne sont pas pleinement des quantités 32 bits et la le dernier octet sera toujours 0. Ce code échouera si vous essayez quelque chose comme mov, eax 0xC000000 – Michael

+0

"chercher les quatre octets" était ce que je cherchais. Merci! –

3

Le premier mov est en train de copier à partir du décalage goo par rapport au registre de segment [e] DS. Le second mov écrit au décalage de foo dans un emplacement de données relatif au registre DS. Si le CS et DS sont coïncidents, alors cela peut être ignoré. En supposant que le CS et le DS sont coïncidents, vous êtes susceptible de courir dans divers mécanismes de protection qui rendent les sections de code en lecture seule.

RE: followups

  1. Un isnt label comme une référence - vous ne déréférencer en tant que tel. L'assembleur se substitue dans un nombre représentant l'emplacement dans le code résultant. Vous pouvez charger l'adresse ou la chose à l'adresse. Le [et] indiquent le déréférencement - J'ai corrigé un élément confus dans ma première réponse pour couvrir ceci. IOW faisant [goo] charge la chose à cette adresse.
  2. Un jeu d'instructions CISC comme x86 possède des instructions de longueur [très] variable - certaines même pas un multiple de la longueur des mots. Les RISC tentent généralement de rendre cela plus clair afin de simplifier les instructions de décodage.
  3. 3 - vous ne modifiez que les 4 premiers octets du mov eax, 2 (qui, en raison du petit codage endian, est remplacé par 4 mais est écrasé par l'instruction suivante qui n'a pas été modifiée du tout - 5 n'est jamais dans le l'image en tant que candidat (je pensais que vous pensiez que le code est réorganisé comme vous avez d'abord posé la question [1], bien que vous en sachiez clairement un peu plus comme je l'aurais deviné de votre représentant: P)]).

Notez que tout cela suppose que CS = DS et DEP ISNT Intervenir.

De plus, si vous utilisez BX au lieu de EBX, le genre de choses que vous attendiez entreront en jeu (en utilisant xX au lieu de ExX accède aux 2 octets bas du registre [et xL accède à l'octet le plus bas])

[1] Rappelez-vous qu'un assembleur est un outil d'écriture d'opcodes - des choses comme des étiquettes, etc. nombres etc. avec très peu de magie ou des transformations impressionnantes du code - il n'y a pas de fermetures ou quelque chose de profond de cette nature qui se cache là-dedans. (Ceci est un peu trop simplifier - le code peut être repositionnable, et dans de nombreux cas se fixups appliqués aux usages de compensations par une combinaison de l'éditeur de liens et le chargeur)

+0

droite - j'étais avec à l'esprit ... RISC merci pour éclaircir ce point –

2

Suivi des réponses:

  1. Il vous donne le code de la machine à partir de l'adresse. Combien de cela dépend de la longueur de votre chargement, dans ce cas, il est de 4 octets.

  2. Il peut s'agir de plusieurs commandes ou seulement d'un fragment d'une commande. Sur cette architecture (Intel x86), les commandes de code machine sont comprises entre 8 et 120 bits.

  3. 3.

Questions connexes