Codificação de instrução simples
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
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