Compare commits
No commits in common. "main" and "main" have entirely different histories.
4 changed files with 44 additions and 211 deletions
37
README.org
37
README.org
|
@ -80,3 +80,40 @@ As datas e tópicos podem mudar de acordo com o desenrolar do curso!
|
||||||
Ao final do curso, será fornecido um certificado de conclusão mediante a
|
Ao final do curso, será fornecido um certificado de conclusão mediante a
|
||||||
apresentação de um projeto final.
|
apresentação de um projeto final.
|
||||||
|
|
||||||
|
* Inscrições e forma de pagamento
|
||||||
|
|
||||||
|
- *Inscrições:* até 27 de junho de 2025
|
||||||
|
- *Valor parcelado:* R$300,00 (em até 6x)
|
||||||
|
- *À vista no PIX:* R$270,00 (10% de desconto)
|
||||||
|
|
||||||
|
* Como se inscrever
|
||||||
|
|
||||||
|
** 1. Realize o pagamento pela forma escolhida
|
||||||
|
|
||||||
|
- *PIX (com desconto):* cursos@blauaraujo.com
|
||||||
|
- *Parcelamentos:* [[https://link.picpay.com/p/17500877656850385526c47][link de pagamento (PicPay)]]
|
||||||
|
|
||||||
|
** 2. Envie um e-mail com seus dados
|
||||||
|
|
||||||
|
*Destinatário:* cursos@blauaraujo.com
|
||||||
|
|
||||||
|
*Informações (obrigatórias):*
|
||||||
|
|
||||||
|
- Comprovante de pagamento
|
||||||
|
- Nome completo
|
||||||
|
- E-mail de contato
|
||||||
|
- CPF ou CNPJ
|
||||||
|
- Endereço postal completo com CEP
|
||||||
|
|
||||||
|
Esses dados são necessários para a emissão da nota fiscal.
|
||||||
|
|
||||||
|
** 3. Aguarde a resposta
|
||||||
|
|
||||||
|
Seu e-mail será respondido em até 24h para confirmar sua inscrição e dar algumas
|
||||||
|
informações sobre o início das aulas. Você também receberá a nota fiscal eletrônica
|
||||||
|
no e-mail informado.
|
||||||
|
|
||||||
|
* Outras informações e casos especiais
|
||||||
|
|
||||||
|
Envie um e-mail para cursos@blauaraujo.com ou me procure no [[https://t.me/blau_araujo][Telegram]].
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,7 @@
|
||||||
|
|
||||||
* 0 -- Introdução à linguagem Assembly (NASM)
|
* 0 -- Introdução à linguagem Assembly (NASM)
|
||||||
|
|
||||||
- [[./aula-00.org][Texto]]
|
[[./aula-00.org][Texto]] | [[#][Vídeo]]
|
||||||
- [[https://youtu.be/NsFUbSoz12c][Vídeo #0: Sobre o curso]]
|
|
||||||
- [[https://youtu.be/LUuNAMezDOM][Vídeo #1: O que é Assembly]]
|
|
||||||
|
|
||||||
*Conteúdo:*
|
|
||||||
|
|
||||||
- O que é Assembly
|
- O que é Assembly
|
||||||
- Linguagem dependente da arquitetura
|
- Linguagem dependente da arquitetura
|
||||||
|
@ -25,11 +21,8 @@
|
||||||
|
|
||||||
* 1 -- Arquitetura de computadores
|
* 1 -- Arquitetura de computadores
|
||||||
|
|
||||||
- [[./aula-01.org][Texto]]
|
[[./aula-01.org][Texto]] | [[#][Vídeo]]
|
||||||
- [[https://youtu.be/nW1OrIisvV0][Vídeo #2: Arquiteturas]]
|
|
||||||
|
|
||||||
*Conteúdo:*
|
|
||||||
|
|
||||||
- Modelo de von Neumann
|
- Modelo de von Neumann
|
||||||
- Arquiteturas x86
|
- Arquiteturas x86
|
||||||
- Componentes de uma CPU x86_64
|
- Componentes de uma CPU x86_64
|
||||||
|
|
|
@ -4,11 +4,6 @@
|
||||||
|
|
||||||
#+options: toc:3
|
#+options: toc:3
|
||||||
|
|
||||||
*Vídeos relacionados:*
|
|
||||||
|
|
||||||
- [[https://youtu.be/NsFUbSoz12c][Sobre o curso]]
|
|
||||||
- [[https://youtu.be/LUuNAMezDOM][O que é Assembly]]
|
|
||||||
|
|
||||||
* Objetivos
|
* Objetivos
|
||||||
|
|
||||||
- Apresentar as características e os elementos básicos da linguagem Assembly.
|
- Apresentar as características e os elementos básicos da linguagem Assembly.
|
||||||
|
@ -17,110 +12,6 @@
|
||||||
- Aprender as instruções e diretivas essenciais para começar a programar.
|
- Aprender as instruções e diretivas essenciais para começar a programar.
|
||||||
- Criar executar um primeiro programa em Assembly.
|
- Criar executar um primeiro programa em Assembly.
|
||||||
|
|
||||||
* Máquina de Turing
|
|
||||||
|
|
||||||
No começo do século 20, surge uma questão no campo da matemática: até onde
|
|
||||||
seria possível solucionar problemas seguindo estritamente um conjunto de
|
|
||||||
regras fixas estabelecidas em um /algoritmo/?
|
|
||||||
|
|
||||||
#+begin_quote
|
|
||||||
*Nota:* em matemática, /algoritmos/ são sequências finitas de ações executáveis
|
|
||||||
que visam obter soluções para determinados tipos de problema.
|
|
||||||
#+end_quote
|
|
||||||
|
|
||||||
Nos anos 1930, o matemático Alan Turing estava trabalhando em um problema de
|
|
||||||
lógica formal (campo que estuda a estrutura de enunciados e suas regras). Como
|
|
||||||
parte do que estava tentando demonstrar, ele precisava encontrar uma forma
|
|
||||||
geral para descrever como algoritmos poderiam ser implementados e executados
|
|
||||||
mecanicamente.
|
|
||||||
|
|
||||||
A partir disso, ele formulou o conceito matemático de uma máquina abstrata que
|
|
||||||
manipularia automaticamente os símbolos em uma fita de acordo com uma tabela
|
|
||||||
de regras: a sua /a-machine/ (de /"automatic machine"/), mais tarde chamada de
|
|
||||||
/Máquina de Turing/ por seu orientador de doutorado -- termo que utilizamos
|
|
||||||
até hoje.
|
|
||||||
|
|
||||||
Então, a Máquina de Turing é um modelo matemático que descreve um dispositivo
|
|
||||||
muito simples que seria capaz de expressar computações arbitrárias e, com
|
|
||||||
isso, explorar as propriedades e as limitações da computação mecânica.
|
|
||||||
|
|
||||||
#+begin_quote
|
|
||||||
*Nota:* /modelos matemáticos computacionais/ são modelos que descrevem como a
|
|
||||||
saída de uma função matemática é computada a partir de uma dada entrada.
|
|
||||||
#+end_quote
|
|
||||||
|
|
||||||
Turing descreveu a imagem física de sua máquina como consistindo de...
|
|
||||||
|
|
||||||
- Uma fita dividida em células contendo símbolos ou espaços vazios;
|
|
||||||
- Um cabeçote para ler e escrever símbolos na fita;
|
|
||||||
- Um registrador de estados, para armazenar o estado corrente de um conjunto
|
|
||||||
finito de estados possíveis;
|
|
||||||
- Uma tabela de instruções que, dado o estado atual e o que estiver sendo
|
|
||||||
lido na fita, diz à máquina o que fazer na sequência.
|
|
||||||
|
|
||||||
Por exemplo:
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
Estado atual: q1
|
|
||||||
|
|
||||||
Fita:
|
|
||||||
┌───┬───┬───┬───┬───┬───┬───┐
|
|
||||||
│ ␣ │ 1 │ 1 │ 0 │ ␣ │ ␣ │ ␣ │
|
|
||||||
...└───┴───┴───┴───┴───┴───┴───┘...
|
|
||||||
↑
|
|
||||||
Cabeçote
|
|
||||||
|
|
||||||
Regra:
|
|
||||||
Se (q1, 0) -> escreva 1, mova para a direita, mude estado para q2
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
*Ilustração moderna:* [[https://www.youtube.com/watch?v=E3keLeMwfHY][vídeo de Mike Davey]]
|
|
||||||
|
|
||||||
Esse modelo simples, apesar de abstrato, revelou-se poderoso o suficiente para
|
|
||||||
representar qualquer cálculo que possa ser feito por um algoritmo. Contudo,
|
|
||||||
a computação sequencial das células de uma fita é lenta demais para aplicações
|
|
||||||
práticas modernas. Mesmo assim, a máquina que Turing descreveu tornou-se uma
|
|
||||||
das principais inspirações para a construção das /unidades de processamento/,
|
|
||||||
utilizadas nos computadores até os nossos dias.
|
|
||||||
|
|
||||||
** Uma longa fita de bits
|
|
||||||
|
|
||||||
Na computação moderna, os nossos programas ainda podem ser vistos como uma
|
|
||||||
fita contendo uma longa sequência de bits (valores binários =0= e =1=). Mas,
|
|
||||||
diferente da máquina de Turing:
|
|
||||||
|
|
||||||
- Os bits são armazenados na memória principal do computador, onde podem ser
|
|
||||||
acessados de forma aleatória e quase instantânea;
|
|
||||||
- Em vez de símbolos individuais por célula e uma tabela de estados, os bits
|
|
||||||
são interpretados em blocos de tamanho fixo, expressando as instruções
|
|
||||||
que a CPU deve executar e os dados envolvidos nessas operações;
|
|
||||||
- A tabela de estados agora está incorporada nos processadores na forma de
|
|
||||||
um conjunto fixo de instruções específico de cada CPU, conhecido como ISA
|
|
||||||
(/Instruction Set Architecture/).
|
|
||||||
|
|
||||||
Portanto, /escrever um programa/ significa, em essência, representar, nessa
|
|
||||||
longa fita de bits, os códigos relativos aos dados e instruções que uma
|
|
||||||
máquina em particular será capaz de interpretar e executar. Isso é o que
|
|
||||||
chamamos de /código de máquina/ (ou, popularmente, /linguagem de máquina/) e,
|
|
||||||
em vários momentos da história da computação, os programas foram escritos
|
|
||||||
desta forma.
|
|
||||||
|
|
||||||
Obviamente, escrever diretamente o código de máquina é um processo demorado,
|
|
||||||
tedioso e propenso a erros. Por isso, já nos anos 1950, começaram a ser
|
|
||||||
criados programas dedicados à tradução de representações simbólicas de
|
|
||||||
instruções para as representações binárias do código de máquina. Na prática,
|
|
||||||
o que esses programas fazem é utilizar as representações simbólicas como um
|
|
||||||
"manual de instruções" para montar o código de máquina correspondente -- daí
|
|
||||||
serem chamados de /montadores/ (ou /assemblers/, em inglês).
|
|
||||||
|
|
||||||
Vale observar que, inicialmente, essas representações simbólicas não eram
|
|
||||||
escritas em arquivos de texto como fazemos hoje. Em geral, os códigos das
|
|
||||||
instruções e dados eram registrados fisicamente, em fitas ou cartões
|
|
||||||
perfurados, que depois eram lidos por máquinas. Assim, uma /linguagem de
|
|
||||||
montagem/ (/assembly language/) já existia, mas ainda se passava por uma longa
|
|
||||||
fase onde o processo de escrita de programas era manual e bastante sujeito
|
|
||||||
a erros mecânicos e operacionais.
|
|
||||||
|
|
||||||
* O que é Assembly
|
* O que é Assembly
|
||||||
|
|
||||||
Assembly é uma linguagem de programação que oferece formas de representar, em
|
Assembly é uma linguagem de programação que oferece formas de representar, em
|
||||||
|
@ -271,7 +162,7 @@ quantos bytes quisermos, em qualquer endereço, desde que tenhamos permissão
|
||||||
do sistema.
|
do sistema.
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* Por que aprender Assembly?
|
** Por que aprender Assembly?
|
||||||
|
|
||||||
*** Entendimento do funcionamento de computadores
|
*** Entendimento do funcionamento de computadores
|
||||||
|
|
||||||
|
@ -543,7 +434,7 @@ Quando escrevemos programas em NASM que serão ligados com outros módulos,
|
||||||
como bibliotecas externas ou arquivos objeto, nós precisamos informar ao
|
como bibliotecas externas ou arquivos objeto, nós precisamos informar ao
|
||||||
editor de ligações quais símbolos devem ser /exportados/ para esses módulos
|
editor de ligações quais símbolos devem ser /exportados/ para esses módulos
|
||||||
e quais devem ser /importados/ de outros lugares. No NASM, isso é feito com
|
e quais devem ser /importados/ de outros lugares. No NASM, isso é feito com
|
||||||
as diretivas =global= (exportação) e =extern= (importação).
|
as diretivas =global= (importação) e =extern= (exportação).
|
||||||
|
|
||||||
No GNU/Linux, especialmente quando não usamos uma linguagem de mais alto
|
No GNU/Linux, especialmente quando não usamos uma linguagem de mais alto
|
||||||
nível (como C), nós precisamos especificar manualmente o ponto de entrada
|
nível (como C), nós precisamos especificar manualmente o ponto de entrada
|
||||||
|
@ -847,7 +738,7 @@ imul destino, origem (resultado em destino)
|
||||||
imul destino, origem, imediato (resultado em destino)
|
imul destino, origem, imediato (resultado em destino)
|
||||||
#+end_example
|
#+end_example
|
||||||
|
|
||||||
- Multiplica =origem= pelo valor de =imediato= e armazena o resultado em =destino=.
|
- Multiplica =origem= pelo valor de =imediato= e armazena o resultado em =origem=.
|
||||||
- Se o resultado exceder a capacidade de =destino=, apenas os bytes mais
|
- Se o resultado exceder a capacidade de =destino=, apenas os bytes mais
|
||||||
baixos serão armazenados (não há extensão de registradores).
|
baixos serão armazenados (não há extensão de registradores).
|
||||||
- Afeta as flags =CF= e =OF= no caso de estouro da capacidade de =destino=.
|
- Afeta as flags =CF= e =OF= no caso de estouro da capacidade de =destino=.
|
||||||
|
@ -1358,20 +1249,19 @@ instalados no seu sistema:
|
||||||
|
|
||||||
- Um editor de código da sua preferência (Vim, Emacs, Geany, etc)
|
- Um editor de código da sua preferência (Vim, Emacs, Geany, etc)
|
||||||
- =git=
|
- =git=
|
||||||
- =nasm= e =ndisasm=
|
- =nasm=
|
||||||
- =gcc=
|
- =gcc=
|
||||||
- =as=
|
- =as=
|
||||||
- =ld=
|
- =ld=
|
||||||
- =gdb=
|
- =gdb=
|
||||||
- =readelf=
|
- =readelf=
|
||||||
- =objdump=
|
- =objdump=
|
||||||
- =objcopy=
|
|
||||||
- =nm=
|
- =nm=
|
||||||
- =ldd=
|
- =ldd=
|
||||||
- =hexedit=
|
- =hexedit=
|
||||||
- =xxd= (geralmente instalado com o editor Vim)
|
- =xxd= (geralmente instalado com o editor Vim)
|
||||||
|
|
||||||
No Debian e derivados, a maioria deles é instalada com os comandos:
|
No Debian, a maioria deles é instalada com os comandos:
|
||||||
|
|
||||||
#+begin_example
|
#+begin_example
|
||||||
sudo apt update
|
sudo apt update
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
* Prefixos REX na arquitetura Intel 64 (x86-64)
|
|
||||||
|
|
||||||
O prefixo REX é um byte opcional usado no modo 64 bits para:
|
|
||||||
|
|
||||||
- Acessar registradores estendidos (~r8–r15~)
|
|
||||||
- Usar operandos de ~64~ bits
|
|
||||||
- Estender campos ~ModR/M~, ~SIB~ ou ~opcode~
|
|
||||||
|
|
||||||
** Formato geral do prefixo REX (1 byte)
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
Bits: 7 6 5 4 | 3 | 2 | 1 | 0
|
|
||||||
0 1 0 0 W R X B
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
| Bit | Nome | Função |
|
|
||||||
|-----+------+--------------------------------------------------------------------|
|
|
||||||
| ~7–4~ | ~0100~ | Identifica o byte como prefixo REX |
|
|
||||||
| ~3~ | ~W~ | ~1~ = operandos de ~64~ bits |
|
|
||||||
| ~2~ | ~R~ | Estende o campo ~Reg~ no byte ~ModR/M~ |
|
|
||||||
| ~1~ | ~X~ | Estende o campo ~Index~ no byte ~SIB~ |
|
|
||||||
| ~0~ | ~B~ | Estende o campo ~Base~ no ~ModR/M~, ~SIB~ ou campo ~reg~ em certos opcodes |
|
|
||||||
|
|
||||||
** Tabela dos 16 prefixos REX possíveis (~0x40–0x4F~)
|
|
||||||
|
|
||||||
| Hex | Binário | ~W~ | ~R~ | ~X~ | ~B~ | Significado resumido |
|
|
||||||
|------+----------+---+---+---+---+-------------------------------------------------|
|
|
||||||
| ~0x40~ | ~01000000~ | ~0~ | ~0~ | ~0~ | ~0~ | Sem extensão nem ~64~-bit |
|
|
||||||
| ~0x41~ | ~01000001~ | ~0~ | ~0~ | ~0~ | ~1~ | ~B = 1~ (extensão do campo Base) |
|
|
||||||
| ~0x42~ | ~01000010~ | ~0~ | ~0~ | ~1~ | ~0~ | ~X = 1~ (extensão do campo Index) |
|
|
||||||
| ~0x43~ | ~01000011~ | ~0~ | ~0~ | ~1~ | ~1~ | ~X = 1~, ~B = 1~ |
|
|
||||||
| ~0x44~ | ~01000100~ | ~0~ | ~1~ | ~0~ | ~0~ | ~R = 1~ (extensão do campo Reg) |
|
|
||||||
| ~0x45~ | ~01000101~ | ~0~ | ~1~ | ~0~ | ~1~ | ~R = 1~, ~B = 1~ |
|
|
||||||
| ~0x46~ | ~01000110~ | ~0~ | ~1~ | ~1~ | ~0~ | ~R = 1~, ~X = 1~ |
|
|
||||||
| ~0x47~ | ~01000111~ | ~0~ | ~1~ | ~1~ | ~1~ | ~R = 1~, ~X = 1~, ~B = 1~ |
|
|
||||||
| ~0x48~ | ~01001000~ | ~1~ | ~0~ | ~0~ | ~0~ | ~W = 1~ (operandos de ~64~ bits) |
|
|
||||||
| ~0x49~ | ~01001001~ | ~1~ | ~0~ | ~0~ | ~1~ | ~W = 1~, ~B = 1~ |
|
|
||||||
| ~0x4A~ | ~01001010~ | ~1~ | ~0~ | ~1~ | ~0~ | ~W = 1~, ~X = 1~ |
|
|
||||||
| ~0x4B~ | ~01001011~ | ~1~ | ~0~ | ~1~ | ~1~ | ~W = 1~, ~X = 1~, ~B = 1~ |
|
|
||||||
| ~0x4C~ | ~01001100~ | ~1~ | ~1~ | ~0~ | ~0~ | ~W = 1~, ~R = 1~ |
|
|
||||||
| ~0x4D~ | ~01001101~ | ~1~ | ~1~ | ~0~ | ~1~ | ~W = 1~, ~R = 1~, ~B = 1~ |
|
|
||||||
| ~0x4E~ | ~01001110~ | ~1~ | ~1~ | ~1~ | ~0~ | ~W = 1~, ~R = 1~, ~X = 1~ |
|
|
||||||
| ~0x4F~ | ~01001111~ | ~1~ | ~1~ | ~1~ | ~1~ | ~W = 1~, ~R = 1~, ~X = 1~, ~B = 1~ (todas as extensões) |
|
|
||||||
|
|
||||||
** Observações
|
|
||||||
|
|
||||||
- O prefixo REX só é válido no modo 64 bits.
|
|
||||||
- Pode ser necessário mesmo com operandos de 32 bits se registradores estendidos
|
|
||||||
forem usados.
|
|
||||||
|
|
||||||
** Exemplo de desmontagem
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
48 89 c8 => mov rax, rcx
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
Nesse caso:
|
|
||||||
- ~48~: É o prefixo REX com ~W = 1~, ~R = 0~, ~X = 0~, ~B = 0~ (operandos de 64 bits).
|
|
||||||
- ~89~: OpCode ~mov r/m, reg~ (como primeiro operando é ~r/m~, temos que ver o byte ModR/M).
|
|
||||||
- ~c8~: Byte ModR/M, onde...
|
|
||||||
|
|
||||||
#+begin_example
|
|
||||||
Bits: 7 8 | 5 4 3 | 2 1 0
|
|
||||||
modo | origem | destino
|
|
||||||
c8 → 11 | 001 | 000
|
|
||||||
regs | rcx | rax
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
Portanto... ~48 89 c8 => mov rax, rcx~
|
|
||||||
|
|
||||||
** Tabela de registradores no byte ModR/M
|
|
||||||
|
|
||||||
O modo ~11~ indica que os dois operandos estão em registradores. Os 3 bits
|
|
||||||
dos campos ~reg~ e ~r/m~ indicam os registradores, com ou sem extensão via
|
|
||||||
prefixo ~REX~.
|
|
||||||
|
|
||||||
| Código | Reg. | ~REX.R~ ou ~REX.B~ |
|
|
||||||
|--------+------+----------------|
|
|
||||||
| ~000~ | ~rax~ | ~r8~ |
|
|
||||||
| ~001~ | ~rcx~ | ~r9~ |
|
|
||||||
| ~010~ | ~rdx~ | ~r10~ |
|
|
||||||
| ~011~ | ~rbx~ | ~r11~ |
|
|
||||||
| ~100~ | ~rsp~ | ~r12~ |
|
|
||||||
| ~101~ | ~rbp~ | ~r13~ |
|
|
||||||
| ~110~ | ~rsi~ | ~r14~ |
|
|
||||||
| ~111~ | ~rdi~ | ~r15~ |
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue