Código de máquina x86 — Parte 1 | Conhecendo

FreeDev
4 min readApr 10, 2019

--

Nota:

Essa série de artigos está incompleta e mal escrita. Se quiser conferir um conteúdo mais novo e completo, leia:

Na parte 1 vamos entender o que é código de máquina, as diferenças entre RISC e CISC e como uma instrução do código de máquina da arquitetura x86 é construída.

Antes de continuar lendo o artigo… Você entende perfeitamente bem o que são sistemas numéricos, não entende?

Na parte 0 vimos o que o código de máquina não é, então vamos entender agora o que ele é. (você esvaziou sua xícara?)
A explicação é muito mais simples do que parece:

Código de máquina é um código interpretado pelo processador. Diferentemente das linguagens de programação que estamos acostumados, o código de máquina não é escrito usando-se de texto. Ele é apenas um conjunto de valores numéricos sem representação em ASCII ou qualquer outro sistema de representação de texto.

Geralmente o código de máquina de computadores digitais é escrito usando o sistema numérico hexadecimal por motivos de praticidade e legibilidade, já que um byte pode ser perfeitamente escrito em apenas dois dígitos hexadecimais.

Sim, é apenas isso. Não vamos entrar em detalhes sobre como o código de máquina é interpretado pelo processador porque o nosso foco é no código de máquina em si. Mas se estiver curioso pesquise por microcode e linguagens de descrição de hardware, como VHDL por exemplo.

Obs.: Se você não está sendo capaz de entender o que é código de máquina ou se ainda acredita que “código de máquina é binário(sic!)”, sugiro a leitura disto aqui.

Diferenças entre CISC e RISC

Resumidamente falando uma arquitetura CISC (Complex Instruction Set Computer) é basicamente uma arquitetura que é composta por um conjunto complexo de instruções. Enquanto RISC (Reduced Instruction Set Computer) é, entre aspas, o seu “oposto” onde este é consistido por um conjunto simples de instruções.

RISC tem poucas instruções no seu código de máquina, e cada uma dessas instruções (ou pelo menos a maioria delas) fazem uma tarefa simples. Como uma analogia pense no JavaScript e suas centenas de frameworks em contraste com a linguagem C.

C é muito mais simples do que JavaScript mas isso também quer dizer que tarefas que são batidas em JavaScript precisam ser feitas manualmente em C. Isso tem vantagens e desvantagens, mas nosso foco não é esse.

Outro detalhe sobre o código de máquina de arquiteturas RISC, é o fato de todas as instruções terem um tamanho fixo e um nível de complexidade fixo.
Por exemplo na arquitetura ARM, que é RISC, todas as instruções do código de máquina tem o tamanho fixo de 4 bytes e são executadas em 1 ciclo de processamento.

É absurdamente mais fácil entender o código de máquina da arquitetura ARM do que da x86, então se quiser desistir dessa série de artigos eu sugiro que procure por material da arquitetura ARM.

CISC tem muitas instruções e cada uma delas tem um nível de complexidade diferente. Algumas são bem simples, outras complexas e outras absurdamente complexas. Essa variação no nível de complexidade faz com que cada instrução leve uma quantidade de ciclos diferente para ser processada.
Existem instruções de vários tamanhos diferentes. Na arquitetura x86 as instruções podem variar de 1 até 17 bytes de tamanho.

Errata: A maior instrução tem na verdade 15 bytes, a explicação é dada na parte 3 como uma curiosidade.

Formato de uma instrução do CDM x86

CC-BY-SA-4.0 Imagem retirada da Wikipédia, eu mesmo que fiz o upload na Wikimedia

A imagem acima é uma figura do manual para desenvolvedores da Intel, mais especificamente o volume 2A, capítulo 2.
Depois nós iremos ver detalhadamente o que cada parte de uma instrução de código de máquina x86 significa, mas por hora vamos ter apenas uma breve descrição.

  • Prefixes: Prefixos tem o tamanho de 1 byte cada um, servem para “modificar” a operação que o processador irá executar. Existem quatro grupos de prefixos e só podemos usar 1 de cada grupo em uma mesma instrução. Ou seja, podemos ter 0 até 4 prefixos em uma mesma instrução.
    (rep movsb)
  • Opcode: O opcode é o valor numérico que especifica para o processador qual operação ele deve executar. O seu tamanho pode variar de 1 até 3 bytes.
    (mov ah, 0x0E)
  • ModR/M: Em instruções que fazem operações em algum endereço de memória, o byte ModR/M serve para especificar informações sobre o modo de endereçamento e o registrador usado como operando, se este existir.
    (mov eax, [ebp])
  • SIB: Dependendo do modo de endereçamento especificado por ModR/M, o byte SIB pode ser necessário para especificar um cálculo que determina o endereço na memória.
    (mov eax, [ebp+esi])
  • Displacement: O deslocamento, caso necessário, é um valor que pode ter o tamanho de 1, 2 ou 4 bytes. Dependendo do valor de ModR/M, este valor serve para complementar o endereçamento como um “deslocamento de endereço”, isto é, um valor de endereço relativo somado com o endereço calculado em ModR/M ou SIB.
    (mov eax, [ebp+0x1A])
  • Immediate: O valor imediato, caso necessário, especifica um valor numérico de 1, 2 ou 4 bytes que serve de operando em algumas instruções.
    (mov ah, 0x0E)

Caso não tenha reparado, eu adicionei exemplos de instruções em Assembly que necessitam de cada campo que eu citei. Deixei em negrito a parte em Assembly que se equivale a parte em código de máquina.
Caso ainda não estivesse crente disso, saiba que Assembly nada mais é que uma maneira mais simples e legível de se escrever o código de máquina.
Instruções em Assembly são consistidas pelas mesmas partes de uma instrução em código de máquina, porém escrito em formato de texto e com adições feitas pelo assembler que facilitam a vida do programador. Como o sistema de labels/rótulos, constantes, instruções pré-processadas etc.

Vou usar muito de comparação com instruções em Assembly para facilitar o entendimento.

Na próxima parte vamos ver:

  • Modos de processamento
  • O opcode

Quem quiser debater assuntos interessantes sobre programação, pode entrar no meu grupo no Facebook:

https://www.facebook.com/groups/fdcasm/

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Written by FreeDev

Por Luiz Felipe Silva | GitHub: @Silva97

No responses yet

Write a response