Codificación de instrucción simple

Oct 07 2020

Tomemos las siguientes instrucciones de montaje:

add    %cl,%bl

Esto se codifica como: 00 cbo 00000000 11001011en binario. Poniendo el cben los campos de bits ModR / M, se ve así:

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

Y, al buscar el campo de registro aquí , obtenemos:

  • mod: 11(modo de direccionamiento de registro)
  • reg: 001(registro cl)
  • r / m: 011(registro bl)

Y creo que 000000dses la addinstrucción, y d=s=0ya que todos son registros. ¿Es esa una comprensión correcta de cómo se codifica esta instrucción? Además, para el esquema de 'codificación completa', sería preciso lo siguiente (en bytes, no en bits):

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

¿Hay algo que me esté perdiendo aquí en mi intento de 'decodificar' la instrucción?

Respuestas

2 PeterCordes Oct 08 2020 at 04:14

Sí, se ve bien.

El patrón general (para las instrucciones de "legado" ALU que respaldan la fecha de 8086) para la codificación de op r/m, rfrente op r, r/m, y de 8 bits vs 16/32 bits hace uso de la baja de 2 bits del byte de código de operación en un patrón regular, pero no hay necesidad confiar en eso.

Intel documenta completamente exactamente lo que sucede con cada codificación de cada instrucción en su manual vol. 2. Consulte la columna Op / En y la tabla de codificación de operandos, addpor ejemplo. (Ver tambiénhttps://ref.x86asm.net/coder64.htmque también especifica qué operando es cuál para cada código de operación). Ambos le permiten saber qué códigos de operación toman un byte ModRM y cuáles no.

Estos, por supuesto, utilizan el orden de sintaxis Intel. Usted está haciendo su vida más complicada al tratar de seguir los manuales y tutoriales mientras usa la sintaxis de AT&T, que invierte el orden de la lista de operandos frente a los manuales de Intel y AMD.

por ejemplo, 00 /rse enumeran como MRcodificación operando, que a partir de la tabla podemos ver es el operando 1 = ModRM:r/m (r, w), así que es leído y escrito, y codificada por el r/mcampo. operando 2 = ModRM:reg (r), por lo que es una fuente de solo lectura codificada por el regcampo.

Dato curioso: 00 00es add [rax], alo AT&Tadd %al, (%rax)

Tenga en cuenta que puede pedirle a GAS que elija la codificación: diferencias de código de operación XOR x86

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

Ver también Diferencia entre MOV r / m8, r8 y MOV r8, r / m8