Encodage d'instructions simples

Oct 07 2020

Prenons les instructions d'assemblage suivantes:

add    %cl,%bl

Ceci est encodé comme:, 00 cbou 00000000 11001011en binaire. En mettant le cbdans les champs de bits ModR / M, cela ressemble à:

  1   1   0   0   1   0  1   1
+---+---+---+---+---+---+---+---+
|  mod  |    reg    |    r/m    |
+---+---+---+---+---+---+---+---+

Et, en regardant le champ de registre ici, nous obtenons:

  • mod: 11(Enregistrer le mode d'adressage)
  • reg: 001(registre cl)
  • r / m: 011(registre bl)

Et, je crois que 000000dsc'est l' addinstruction, et d=s=0puisque ce sont tous des registres. Est-ce une compréhension correcte de la façon dont cette instruction est codée? De plus, pour le schéma de `` codage complet '', les éléments suivants seraient-ils précis (en octets et non en bits):

[empty]         0x0         0b11001011     [empty]        [empty]          [empty]
_ _ _ _        _ _             _              _           _ _ _ _          _ _ _ _
Prefix      Instruction    Mod-reg-r/m      Scale       displacement      immediate

Y a-t-il des choses qui me manquent ici dans ma tentative de «décoder» l'instruction?

Réponses

2 PeterCordes Oct 08 2020 at 04:14

Oui, ça a l'air bien.

Le modèle général (pour les instructions ALU "héritées" qui remontent à 8086) pour le codage op r/m, rcontre op r, r/m, et 8 bits contre 16/32 bits utilise les 2 bits bas de l'octet d'opcode dans un modèle régulier, mais ce n'est pas nécessaire se fier à cela.

Intel documente entièrement ce qui se passe pour chaque encodage de chaque instruction dans son manuel vol.2. Voir la colonne Op / En et le tableau de codage des opérandes addpar exemple. (Voir égalementhttps://ref.x86asm.net/coder64.htmqui spécifie également quel opérande est lequel pour chaque opcode). Ceux-ci vous permettent de savoir quels opcodes prennent un octet ModRM et lesquels ne le font pas.

Ceux-ci utilisent bien sûr l'ordre de la syntaxe Intel. Vous vous compliquez la vie en essayant de suivre les manuels et les didacticiels tout en utilisant la syntaxe AT&T qui inverse l'ordre de la liste d'opérandes par rapport aux manuels Intel et AMD.

par exemple, 00 /rest répertorié comme MRencodage d'opérande, qui dans la table que nous pouvons voir est l'opérande 1 = ModRM:r/m (r, w), donc il est lu et écrit, et encodé par le r/mchamp. opérande 2 = ModRM:reg (r), donc c'est une source en lecture seule encodée par le regchamp.

Fait amusant: 00 00est add [rax], al, ou AT&Tadd %al, (%rax)

Notez que vous pouvez demander à GAS de choisir l'un ou l'autre encodage: différences d'opcode x86 XOR

{load}  add    %cl,%bl        # 02 d9
{store} add    %cl,%bl        # 00 cb

Voir aussi Différence entre MOV r / m8, r8 et MOV r8, r / m8