Codificação de instrução simples

Oct 07 2020

Vamos pegar a seguinte instrução de montagem:

add    %cl,%bl

Isso é codificado como: 00 cbou 00000000 11001011em binário. Colocando o cbnos campos de bits ModR / M, parece:

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

E, ao consultar o campo de registro , obtemos:

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

E, eu acredito que 000000dsé a addinstrução, e d=s=0já que são todos registros. É uma compreensão correta de como essa instrução é codificada? Além disso, para o esquema de 'codificação completa', o seguinte seria preciso (em bytes, não em bits):

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

Há alguma coisa que estou perdendo aqui na minha tentativa de 'decodificar' a instrução?

Respostas

2 PeterCordes Oct 08 2020 at 04:14

Sim, parece certo.

O padrão geral (para instruções ALU "legadas" que datam de 8086) para codificação op r/m, rvs. op r, r/me 8 bits vs. 16/32 bits usa os 2 bits baixos do byte opcode em um padrão regular, mas não há necessidade confiar nisso.

A Intel documenta totalmente exatamente o que está acontecendo para cada codificação de cada instrução em seu manual vol.2. Consulte a coluna Op / En e a tabela de codificação de operando, addpor exemplo. (Veja tambémhttps://ref.x86asm.net/coder64.htmque também especifica qual operando é qual para cada opcode). Ambos permitem saber quais opcodes usam um byte ModRM e quais não.

É claro que eles usam a ordem da sintaxe Intel. Você está complicando a sua vida tentando seguir manuais e tutoriais enquanto usa a sintaxe AT&T, que inverte a ordem da lista de operandos em comparação com os manuais da Intel e AMD.

por exemplo, 00 /restá listado como MRcodificação de operando, que na tabela podemos ver é operando 1 = ModRM:r/m (r, w), portanto, é lido e escrito e codificado pelo r/mcampo. operando 2 = ModRM:reg (r), portanto, é uma fonte somente leitura codificada pelo regcampo.

Curiosidade: 00 00é add [rax], al, ou AT&Tadd %al, (%rax)

Observe que você pode pedir ao GAS para escolher a codificação: diferenças de opcode x86 XOR

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

Veja também a diferença entre MOV r / m8, r8 e MOV r8, r / m8