forked from blau_araujo/pbn
Compare commits
5 commits
Author | SHA1 | Date | |
---|---|---|---|
a853524d46 | |||
a2bdba6e1f | |||
c16e8e9261 | |||
0c2341b669 | |||
05d5566979 |
4 changed files with 211 additions and 44 deletions
37
README.org
37
README.org
|
@ -80,40 +80,3 @@ 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,7 +6,11 @@
|
||||||
|
|
||||||
* 0 -- Introdução à linguagem Assembly (NASM)
|
* 0 -- Introdução à linguagem Assembly (NASM)
|
||||||
|
|
||||||
[[./aula-00.org][Texto]] | [[#][Vídeo]]
|
- [[./aula-00.org][Texto]]
|
||||||
|
- [[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
|
||||||
|
@ -21,7 +25,10 @@
|
||||||
|
|
||||||
* 1 -- Arquitetura de computadores
|
* 1 -- Arquitetura de computadores
|
||||||
|
|
||||||
[[./aula-01.org][Texto]] | [[#][Vídeo]]
|
- [[./aula-01.org][Texto]]
|
||||||
|
- [[https://youtu.be/nW1OrIisvV0][Vídeo #2: Arquiteturas]]
|
||||||
|
|
||||||
|
*Conteúdo:*
|
||||||
|
|
||||||
- Modelo de von Neumann
|
- Modelo de von Neumann
|
||||||
- Arquiteturas x86
|
- Arquiteturas x86
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
|
|
||||||
#+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.
|
||||||
|
@ -12,6 +17,110 @@
|
||||||
- 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
|
||||||
|
@ -162,7 +271,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
|
||||||
|
|
||||||
|
@ -434,7 +543,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= (importação) e =extern= (exportação).
|
as diretivas =global= (exportação) e =extern= (importaçã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
|
||||||
|
@ -738,7 +847,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 =origem=.
|
- Multiplica =origem= pelo valor de =imediato= e armazena o resultado em =destino=.
|
||||||
- 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=.
|
||||||
|
@ -1249,19 +1358,20 @@ 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=
|
- =nasm= e =ndisasm=
|
||||||
- =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, a maioria deles é instalada com os comandos:
|
No Debian e derivados, a maioria deles é instalada com os comandos:
|
||||||
|
|
||||||
#+begin_example
|
#+begin_example
|
||||||
sudo apt update
|
sudo apt update
|
||||||
|
|
87
docs/prefixo-rex.org
Normal file
87
docs/prefixo-rex.org
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
* 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