Prévia do material em texto
Unidade III
Controlando Execuções em Assembly
Linguagem de
Montagem
Diretor Executivo
DAVID LIRA STEPHEN BARROS
Gerente Editorial
ALESSANDRA VANESSA FERREIRA DOS SANTOS
Projeto Gráfico
TIAGO DA ROCHA
Autoria
GISELLE AZEVEDO PINTO
AUTORIA
Giselle Azevedo Pinto
Olá. Sou formada em Sistemas de Informação e pós-graduada em
Cibersegurança e em Produção e Sistemas, mestra em Engenharia de
Produção, com experiência técnico-profissional de mais de 20 anos na
área de Tecnologia da Informação. Sou apaixonada pelo que faço e adoro
transmitir minha experiência de vida àqueles que estão iniciando em suas
profissões. Por isso, fui convidada pela Editora Telesapiens a integrar seu
elenco de autores independentes. Estou muito feliz em poder ajudar você
nesta fase de muito estudo e trabalho. Conte comigo!
ICONOGRÁFICOS
Olá. Esses ícones irão aparecer em sua trilha de aprendizagem toda vez
que:
OBJETIVO:
para o início do
desenvolvimento
de uma nova
competência;
DEFINIÇÃO:
houver necessidade
de apresentar um
novo conceito;
NOTA:
quando necessárias
observações ou
complementações
para o seu
conhecimento;
IMPORTANTE:
as observações
escritas tiveram que
ser priorizadas para
você;
EXPLICANDO
MELHOR:
algo precisa ser
melhor explicado ou
detalhado;
VOCÊ SABIA?
curiosidades e
indagações lúdicas
sobre o tema em
estudo, se forem
necessárias;
SAIBA MAIS:
textos, referências
bibliográficas
e links para
aprofundamento do
seu conhecimento;
REFLITA:
se houver a
necessidade de
chamar a atenção
sobre algo a ser
refletido ou discutido;
ACESSE:
se for preciso acessar
um ou mais sites
para fazer download,
assistir vídeos, ler
textos, ouvir podcast;
RESUMINDO:
quando for preciso
fazer um resumo
acumulativo das
últimas abordagens;
ATIVIDADES:
quando alguma
atividade de
autoaprendizagem
for aplicada;
TESTANDO:
quando uma
competência for
concluída e questões
forem explicadas;
SUMÁRIO
Acesso à memória em Assembly .......................................................... 10
A memória ............................................................................................................................................10
Endereços de memória ............................................................................................................... 11
Instruções de transferência na memória ....................................................................... 13
Estruturas condicionais no Assembly................................................. 18
Instruções de transferência de controle ....................................................................... 20
Analisando a estrutura condicional SWITCH de alto nível em
Assembly ...............................................................................................................................................28
Estruturas de repetição do Assembly ................................................ 33
Prefixos de repetição ....................................................................................................................37
Operações de laço e repetição ........................................................................................... 38
Executando um loop no EMU8086................................................................................... 39
Programação dos chips em Assembly ................................................43
Placa-mãe ............................................................................................................................................43
Chipset .....................................................................................................................................................45
Programando os chips .................................................................................................................47
7
UNIDADE
03
Linguagem de Montagem
8
INTRODUÇÃO
Você sabia que a área de linguagem de montagem é uma das mais
demandadas na indústria e será responsável pela geração de muitos
empregos nos próximos 10 anos? Isso mesmo. A linguagem de montagem
está presente em todas as máquinas de uma empresa, indústria ou fábrica,
independentemente do tipo de fabricante. A linguagem de montagem é
uma linguagem universal para o ambiente tecnológico. Nesta unidade,
iremos estudar sobre controle de execuções em Assembly. Iremos aplicar
o recurso de endereçamento de memória em linguagem de montagem
Assembly. Veremos também como aplicar estruturas condicionais em
linguagem de montagem. Em seguida, estudaremos as estruturas de
repetição para otimização de programas em linguagem de montagem e,
para finalizar, iremos aplicar a programação em chips. Entendeu? Ao longo
desta unidade letiva, você vai mergulhar neste universo!
Linguagem de Montagem
9
OBJETIVOS
Olá. Seja muito bem-vindo à Unidade 3. Nosso objetivo é auxiliar
você no desenvolvimento das seguintes competências profissionais até o
término desta etapa de estudos:
1. Aplicar o recurso de endereçamento de memória em linguagem
de montagem Assembly.
2. Aplicar estruturas condicionais em linguagem de montagem.
3. Usar estruturas de repetição para otimização de programas em
linguagem de montagem.
4. Aplicar a programação em chips.
Linguagem de Montagem
10
Acesso à memória em Assembly
OBJETIVO:
Ao término deste capítulo, você será capaz de aplicar o
recurso de endereçamento de memória em linguagem de
montagem Assembly. E então? Motivado para desenvolver
essa competência? Então, vamos lá. Avante!
A memória
O que é memória? Dizemos que memória é a parte do computador
na qual dados e programas são armazenados. Alguns pesquisadores usam
a palavra “armazém” ou “armazenagem” em vez da palavra “memória”.
Figura 1 – Tipos de memórias
Fonte: Pixabay
IMPORTANTE:
Nos dias atuais, o uso da palavra “armazenagem” está sendo
cada vez mais frequente para se referir à armazenagem em
disco.
Linguagem de Montagem
11
REFLITA:
“Sem uma memória que os processadores possam ler e na
qual possam gravar, ou escrever, informações, não haveria
computadores digitais com programas armazenados”
(TANENBAUM; AUSTIN, 2013, p. 57).
O acesso à memória é um enorme gargalo em todos os
computadores modernos porque as CPUs são muito mais rápidas do
que a memória (TANENBAUM; AUSTIN, 2013). Muitos processadores
rápidos, acessando a memória utilizando o mesmo barramento, podem
gerar conflitos (e isso é bastante comum, pois os processadores são mais
rápidos que a memória!).
Alguns processadores estão sendo projetados com um pouco de
memória local destinado só para eles. Essa memória não é acessível para
os outros recursos computacionais. “O acesso a essa memória privada não
usa o barramento principal, o que reduz muito o tráfego no barramento”
(TANENBAUM; AUSTIN, 2013, p. 56).
Figura 2 – Multiprocessador com barramento único (a) e multicomputador com memórias
locais (b)
Fonte: Tanenbaum e Austin (2013, p. 56).
Endereços de memória
As memórias são quantidade de células, nas quais cada uma pode
armazenar um tipo de informação.
Linguagem de Montagem
12
Cada célula tem um número, denominado seu endereço,
pelo qual os programas podem se referir a ela. Se a
memória tiver n células, elas terão endereços de 0 a n –
1. Todas as células em uma memória contêm o mesmo
número de bits. (TANENBAUM; AUSTIN, 2013, p. 58)
A seguir, temos uma figura que mostra três organizações diferentes
para uma memória de 96 bits (TANENBAUM; AUSTIN, 2013).
Figura 3 –Três maneiras de organizar uma memória de 96 bits
Fonte: Tanenbaum e Austin (2013, p. 58).
VOCÊ SABIA?
O número de bits no endereço determina o número máximo
de células diretamente endereçáveis na memória e é
independente do número de bits por célula. Uma memória
com 212 células de 8 bits cada e uma memória com 212
células de 64 bits cada precisam de endereços de 12 bits.
(TANENBAUM; AUSTIN, 2013, p. 58)
Linguagem de Montagem13
Instruções de transferência na memória
Em linguagem de montagem Assembly, usamos comandos
específicos para manipular as informações que estão armazenadas nas
células de memória do computador. Usamos instruções para mover a
informação, ou o conteúdo, dos operadores, e as instruções podem ser
usadas de diferentes formas para endereçamento de memória.
O comando MOV pode ser usado da seguinte forma:
MOVS (MOVSB) (MOVSW)
O objetivo do comando MOV é efetuar a transferência de dados
entre células de memória, acumulador e os registradores.
A sintaxe do comando MOV é:
MOV Destino,Fonte
Em que, “Destino” é para onde o dado vai ser movido e a “Fonte” é
onde a informação, ou o dado, está.
O comando MOV permite diferentes movimentos, nos quais os
dados permitidos nessa instrução são:
• MOV memória, acumulador
• MOV acumulador, memória
• MOV registrador de segmento, memória/registrador
• MOV memória/registrador, registrador de segmento
• MOV registrador, registrador
• MOV registrador, memória
• MOV memória, registrador
• MOV registrador, dado imediato
• MOV memória, dado imediato
Exemplos da aplicação do comando MOV:
MOV AX,0008h
Linguagem de Montagem
14
MOV BX,AX
MOV AX,4C01h
INT 21h
O programa anterior permite mover o valor 0008h para o registrador
AX e depois mover o conteúdo de AX (0008h) para outro registrador, o BX,
e por fim, mover o valor 4C01h para o registrador AX, terminando, assim, a
execução com a opção 4C da interrupção 21h.
Outro comando usado para a transferência de dados da memória
é o MOVS (MOVSB) (MOVSW). O objetivo do comando MOVS é mover
byte ou então cadeias de palavra da fonte, que são endereçadas por SI
(Source Index), e destinadas para o endereçado por DI (Destiny Index).
Vale lembrar que SI e DI são registradores.
A sintaxe do comando MOVS é:
MOVS
Que pode ser usado sem a necessidade de complementos no
argumento, uma vez que toma como endereço-fonte o próprio conteúdo
do registrador SI e toma como destino o próprio conteúdo de DI. Podemos
observar isso no exemplo que se segue:
MOV SI, OFFSET VAR01
MOV DI, OFFSET VAR02
MOVS
No exemplo anterior, damos início aos valores de SI e DI, que são
alimentados com os endereços das variáveis VAR01 e VAR02. Depois, é
executado o MOVS, no qual o conteúdo de VAR01 é totalmente copiado
para VAR02.
Os comandos MOVSB e MOVSW são usados da mesma forma
que MOVS. O primeiro comando move um byte (MOVSB) e o segundo
comando move uma Word (MOVSW).
Linguagem de Montagem
15
Podemos usar também as instruções de carga, que são instruções
bem específicas para registradores, utilizadas para carregar bytes ou
também cadeias de bytes em um registrador.
Os comandos usados para carga de instruções são:
LODS (LODSB) (LODSW)
LDS
LEA
LAHF
LES
O comando LODS (LODSB) (LODSW) tem o objetivo de carregar
cadeias, podendo ser de um byte ou cadeia de uma palavra para o
acumulador.
A sintaxe do comando é:
LODS
Em que essa instrução coleta a cadeia encontrada no endereço
indicado por SI, carrega no registrador AL (ou também no AX) e depois
adiciona ou subtrai, o que vai depender do estado de DF, para indicar a
SI se será uma transferência de bytes ou uma transferência de palavras.
MOV SI, OFFSET VAR1
LODS
Podemos ver, na primeira linha, a carga do endereço da variável de
VAR1 em SI. Na segunda linha, o conteúdo daquele local é tomado para
o registrador AL. As instruções LODSB e LODSW podem ser usadas do
mesmo jeito. A primeira instrução carrega um byte e a segunda instrução
carrega uma palavra, usando todo o registrador AX.
A instrução LAHF tem o objetivo de transferir todo o conteúdo
referente aos flags para o registrador AH.
A sintaxe da instrução é:
LAHF
Linguagem de Montagem
16
Em que a instrução é muito importante para verificar o estado dos
flags enquanto o programa é executado.
Podemos ver os flags que serão deixados no registrador (em ordem):
SF ZF ?? AF ?? PF ?? CF
O símbolo “??” pode significar um valor que pode ser indefinido
naqueles bits.
A instrução LDS tem o objetivo de carregar o registrador referente
ao segmento de dados.
A sintaxe da instrução é:
LDS destino,fonte
Em que o operador-fonte pode ser uma double word que fica
na memória. Temos a palavra associada e com o maior endereço, que
é transferida para DS, ou seja, isso passa a ser como o endereço de
segmento. Aqui, a palavra que está associada e com o menor endereço
é o endereço de deslocamento, e será depositada no registrador que foi
indicado como destino.
A instrução LEA pode carregar o endereço referente ao operador-
fonte.
A sintaxe da função é:
LEA destino,fonte
O operador-fonte deve estar localizado na memória, e seu
deslocamento é colocado no registrador de índice ou também no ponteiro
especificado no destino.
Para exemplificar as facilidades que podemos ter com esse
comando, temos:
MOV SI,OFFSET VAR1
O comando precdente é equivalente ao comando:
LEA SI,VAR1
Linguagem de Montagem
17
As pessoas que programam podem achar mais fácil elaborar
programas usando este último formato, principalmente se o programa for
grande.
RESUMINDO:
E então? Gostou do que lhe mostramos? Aprendeu mesmo
tudinho? Agora, só para termos certeza de que você
realmente entendeu o tema de estudo deste capítulo,
vamos resumir tudo o que vimos. Você deve ter aprendido
que a memória é uma parte importante dos recursos do
computador. Quando ocorre o processamento de dados,
principalmente por processadores mais novos e rápidos,
o acesso à memória se torna um gargalo, podendo deixar
a máquina mais lenta. A linguagem de montagem faz o
acesso à memória e consegue manipular e mover os dados
da mesma forma que as operações de máquina. Para
disponibilizar as ferramentas para manipular os dados na
memória, o Assembly possui comandos específicos, como
o MOVS, que move a cadeia de caracteres, podendo dar
tratamento específico quando esses dados são somente
bytes ou quando utilizam o padrão word.
Linguagem de Montagem
18
Estruturas condicionais no Assembly
OBJETIVO:
Ao término deste capítulo, você será capaz de aplicar
estruturas condicionais em linguagem de montagem
Assembly. E então? Motivado para desenvolver essa
competência? Então vamos lá. Avante!
VOCÊ SABIA?
As estruturas condicionais estão presentes em todas
as linguagens de programação, sendo que a estrutura
condicional em linguagem de montagem é um pouco
diferente.
Figura 4 – Desvios
Fonte: Pixabay
Vamos comparar uma estrutura condicional de alto nível que foi
escrita em linguagem C++ e a mesma estrutura condicional escrita em
nível de montagem Assembly. Vamos ver, no exemplo a seguir, uma
estrutura condicional em linguagem de alto nível C++:
Linguagem de Montagem
19
void test(){
int var = 0;
if int (var==0)
{
var=var+1
}
else
{
var=var -1
}
}
Agora, veremos uma estrutura condicional em linguagem de
montagem:
teste():
push %rbp
mov %rbp, %rsp
mov DWORD PTR [%rbp-4],0
cmp DWORD PTR [%rbp-4],0
jne .L2
inc DWORD PTR [%rbp-4]
jmp .L6
.L2:
dec DWORD PTR [%rbp-4]
.L6:
leave
ret
Linguagem de Montagem
20
Quadro 1 – Comparação entre linguagem de alto nível e linguagem de baixo nível
C++ Assembly
void test(){
teste():
push %rbp
mov %rbp, %rsp
int var = 0; mov DWORD PTR [%rbp-4],0
if int (var==0)
cmp DWORD PTR [%rbp-4],0
jne .L2
{
var=var+1
}
inc DWORD PTR [%rbp-4]
jmp .L6
else
{
var=var -1
}
.L2:
dec DWORD PTR [%rbp-4]
}
.L6:
leave
ret
Fonte: Elaborado pela autora com base em Kundra (2020, online).
Comparando os dois códigos, conseguimos identificar semelhanças.
Na linguagem Assembly, podemos ver os comandos CMP, o pulo
condicional JNE (jump not equal) e os possíveis cursos de execução da
estrutura.
Instruções de transferência de controle
Temos osmicroprocessadores da família 80XX, que permitem que
o controle do fluxo relacionado à execução seja transferido em formato
condicional ou incondicional.
Quando falamos de modo condicional de transferência, nos
referimos a como é feita a inicialização no estado ou na combinação
de estados dos flags. Aqui, as transferências incondicionais sempre são
executadas.
Linguagem de Montagem
21
Figura 5 – Desvios usados em estruturas condicionais
200
201
202
203
210
211
225
235
SUB X,Y
BRZ 211
BR 202
BRE R1,
R2, 235
Endereço
de memória
Desvio
incondicional
Desvio
condicional
Desvio
condicional
Instrução
Fonte: Stallings (2010, p. 304).
Na transferência condicional, quando temos uma instrução de
transferência de controle condicional, estamos nos referimos aos desvios
(jumps) que têm o poder de transferir a execução do programa se o estado
do flag for o mesmo que está na instrução.
A sintaxe do comando é:
J(condição) - Desvio curto se condição é satisfeita
O objetivo do comando apresentado é fazer desviar o fluxo do
processamento para o outro operando, no qual uma condição que foi
testada seja encontrada.
Linguagem de Montagem
22
REFLITA:
A distância do endereço que é o alvo, para o desvio que
se quer direcionar, deve estar entre -128 até +127 bytes da
outra instrução.
Na figura que se segue, temos alguns exemplos de comandos de
condicionais em Assembly usando o J (condição). Os flags usados nessa
figura são os seguintes:
CF - Carry Flag.
ZF - Zero Flag.
SF - Sign Flag.
OF - Overflow Flag.
PF - Parity Flag.
Figura 6 – Comandos condicionais em Assembly
Desvios condicionais não sinalizados
Mnemônico Estado dos fl ags Descrição
JA/JNBE (CF ou ZF)=0
Acima/Não abaixo
ou igual
JAE/JNB CF=0
Acima ou igual/Não
abaixo
JB/JNAE CF=1
Abaixo/Não acima
ou igual
JBE/JNA (CF ou ZF)=1
Abaixo ou igual/Não
acima
JC CF=1 Carry
JE/JZ ZF=1 Igual/Zero
JNC CF=0 Não carry
JNE/JNZ ZF=0 Não igual/Não zero
JNP/JPO PF=0
Sem paridade/
Paridade ímpar
Linguagem de Montagem
23
Desvios condicionais sinalizados
JG/JNLE ((SF ⊕ OF) ou ZF)=0
Maior/Não menor ou
igual
JGE/JNL (SF ⊕ OF)=0
Maior ou igual/Não
menor
JL/JNGE (SF ⊕ OF)=1
Menor/Não maior ou
igual
JLE/JNG ((SF ⊕ OF) ou ZF)=1
Menor ou igual/Não
maior
JNO OF=0
Sem estouro
(overfl ow)
JNS SF=0
Sem sinal (não
negativo)
Fonte: Rocha (2021, p. 32).
IMPORTANTE:
Em relação aos desvios incondicionais, podemos dizer
que, normalmente, a unidade de controle (UC) executa
as instruções na sequência em que estão na memória,
sendo que essa sequência pode, em algum momento, ser
alterada por uma instrução de desvio.
Linguagem de Montagem
24
Figura 7 – Representações de estruturas JUMP e LOAD
Tipo de
instrução
Opcode
Representação
simbólica
Descrição
Transferência
de dados
00001010 LOAD MQ
Transfere o conteúdo
de MQ para AC
00001001 LOAD MQ,M(X)
Transfere o conteúdo
do local de memória
X para MQ
00100001 STOR M(X)
Transfere o conteúdo
de AC para o local de
memória X
00000001 LOAD M(X)
Transfere M(X) para
o AC
00000010 LOAD – M(X)
Transfere – M(X) para
o AC
00000011 LOAD |M(X)|
Transfere o valor
absoluto de M(X)
para o AC
00000100 LOAD – |M(X)|
Transfere -|M(X)| para
o acumulador
Desvio
incondicional
00001101 JUMP M(X,0:19)
Apanha a próxima
instrução da metade
esquerda de M(X)
00001110 JUMP M(X,20:39)
Apanha a próxima
instrução da metade
direita de M(X)
Desvio
condicional
00001111 JUMP+ M(X,0:19)
Se o número no AC
for não negativo,
apanha a próxima
instrução da metade
esquerda de M(X)
00010000 JUMP+ M(X,20:39)
Se o número no AC
for não negativo,
apanha a próxima
instrução da metade
direita de M(X)
Fonte: Stallings (2010, p. 18).
Linguagem de Montagem
25
O desvio condicional é um tipo de desvio que pode se tornar
dependente da condição, em que os seguintes pontos de decisão podem
ser permitidos:
• Operações aritméticas realizadas pela ALU.
• Modificação de endereço permitindo que sejam calculados na ALU
e, em seguida, inseridos em instruções armazenadas na memória.
Esse recurso permite uma flexibilidade de endereçamento em
relação ao programa de forma considerável.
A instrução JMP, que é utilizada para desviar a execução, tem
o objetivo de provocar um desvio de forma incondicional no fluxo de
processamento, transferindo a execução para o operando-alvo.
O desvio pode ser realizado dentro ou fora do segmento de código.
Quando ocorre desvio dentro do próprio segmento, chamamos de desvio
intrassegmento e, nesse caso, somente o registrador IP é afetado quando
a instrução é executada, em que o valor endereço-alvo é alterado.
VOCÊ SABIA?
Quando a distância entre o valor atual e o endereço-alvo
está entre -128 a +127 bytes, podemos chamar de desvio-
curto (JMP SHORT), conhecido também como desvio
incondicional relativo curto.
Exemplo:
label 1: ----------------------
----------------------
atual : JMP label 1
A outra forma de desvio incondicional é o desvio intersegmento.
Nesse caso, os valores do CS e do IP precisam ser alterados para que
ocorra a migração de um segmento para outro. O código que identifica
um desvio incondicional para outro segmento deve ser seguido por 4
bytes: os dois primeiros contendo o novo valor do IP e os dois seguintes o
novo valor do CS.
Linguagem de Montagem
26
Exemplo:
----------------------
atual: JMP novo_longe —> Segmento de código atual
----------------------
----------------------
novo_longe: MOV AX, 10h —> Segmento de código novo
----------------------
As formas de especificar um desvio incondicional, vistas até aqui,
são ditas diretas, pois o endereço da posição-alvo que se deseja atingir
é explicitamente especificado na instrução, quer com um valor numérico,
quer por um “label”. A outra forma de se executar um desvio incondicional
é a indireta, na qual o valor do endereço-alvo está armazenado em
registrador(es) ou em posição(ões) de memória, o qual será movido para o
registrador IP, no caso de desvio intrassegmento ou para os registradores
IP e CS, no caso de desvio intersegmento (ROCHA, 2021).
Sintaxe do comando:
JMP alvo
Exemplos da instrução JUMP:
JMP desvio_curto ; Direto, intra-segmento, relativo.
JMP desvio_intra ; Direto, intra-segmento.
JMP desvio_inter ; Direto, inter-segmento.
JMP CX ; Indireto, intra-segmento, o endereço-alvo está armazenado
em CX.
JMP dword ptr[BX] ; Indireto, inter-segmento, o endereço-alvo está
armazenado nas 4 posições de memória a partir de DS:BX.
Outras instruções que podem ser usadas em estruturas condicionais
ou incondicionais estão elencadas no quadro a seguir.
Linguagem de Montagem
27
Quadro 2: Estruturas e suas funções
COMANDO FUNÇÃO
CALL Chamar uma sub-rotina, alterando o fl uxo normal
de execução, processar uma sub-rotina e ao fi m
dela, permitir que a execução retorne ao ponto do
programa imediatamente posterior à instrução de
chamada da sub-rotina.
Exemplos: CALL sub_proxima ; Direta, intra-
segmento
CALL sub_distante ; Direta, inter-segmento
CALL BX ; Indireta, intra-segmento
CALL dword ptr [SI] ; Indireta, inter-segmento
RET Encerrar uma sub-rotina, transferindo o fl uxo do
processamento para a instrução seguinte à chamada
da sub-rotina. O endereço dessa instrução, para
onde deve ser dado o retorno, foi colocado na pilha
pela instrução CALL. Portanto, para encerrar uma
sub-rotina “near”, que reside no mesmo segmento, a
instrução RET deverá apenas retirar uma palavra do
topo da pilha e movê-la para o registrador IP.
Sintaxe do comando RET: RET
INT Alterar o fl uxo normal de execução do programa,
desviando-se para uma rotina de interrupção, cujo
vetor (endereço formado por CS:IP) está presente
numa tabela nos primeiros 1024 bytes da memória.
A tabela de vetores de interrupção tem 256 entradas,
cada qual com 4 bytes (os dois primeiros contendo
o valor do IP e os dois seguintes o valor do CS), queindicam o endereço de uma rotina na memória.
Sintaxe do comando INT: INT tipo
IRET Retornar de uma rotina de tratamento de
interrupção. Essa instrução simplesmente recupera
da pilha o conteúdo dos registradores que
foram automaticamente salvos, na ocorrência da
interrupção.
Sintaxe do comando IRET: IRET
Fonte: Rocha (2021, p. 30).
Linguagem de Montagem
28
Analisando a estrutura condicional
SWITCH de alto nível em Assembly
VOCÊ SABIA?
A estrutura SWITCH é uma estrutura condicional muito
usada em linguagens de alto nível, conhecida como SWITCH
CASE ou ESCOLHA CASO, e facilita a programação quando
temos muitas condições para colocar em uma condicional
IF, evitando, assim, muitas estruturas IF aninhadas.
Vamos falar de outro exemplo de condicional em linguagem de alto
nível que é o comando switch (escolha caso). No exemplo que se segue,
podemos ver o exemplo de um comando switch na linguagem C++:
[WILEVESECURITY]
void test(){
int var=0;
switch (var==0)
{
case 0:
var=var+1;
break;
case 1:
var=var -1 ;
break;
default:
var=5;
break;
}
Linguagem de Montagem
29
}
Agora vamos ver o mesmo comando em linguagem Assembly:
[WILEVESECURITY]
test:
push rbp
mov rbp,rsp
mov DWORD PTR[rbp-4],0
cmp DWORD PTR [rbp-4],0
je .L2
cmp DWORD PTR [rbp-4],1
je .L3
jmp .L6
.L2:
add DWORD PTR [rbp-4],1
jmp .L5
.L3:
sub DWORD PTR [rbp-4],1
jmp .L5
.L6:
mpv DWORD PTR [rbp-4],5
nop
.L5:
nop
pop rbp
ret
Linguagem de Montagem
30
Agora vamos comparar os dois códigos e identificar as semelhanças
das estruturas de alto nível, por meio da linguagem C++, e da estrutura de
baixo nível, em linguagem de montagem Assembly.
Quadro 3: Comparação entre linguagens C++ e Assembly (condicional)
C++ Assembly
void test(){ test:
push rbp
mov rbp,rsp
int var=0; mov DWORD PTR[rbp-4],0
switch (var==0) cmp DWORD PTR [rbp-4],0
je .L2
cmp DWORD PTR [rbp-4],1
je .L3
jmp .L6
{
case 0:
var=var+1;
.L2:
add DWORD PTR [rbp-4],1
break; jmp .L5
case 1:
var=var -1 ;
.L3:
sub DWORD PTR [rbp-4],1
break; jmp .L5
default:
var=5;
.L6:
mpv DWORD PTR [rbp-4],5
break;
}
nop
}
.L5:
nop
pop rbp
ret
Fonte: Elaborado pela autora com base em Kundra (2020, online).
Na figura subsequente, temos outros comandos em linguagem
Assembly que podem executar os saltos condicionais.
Linguagem de Montagem
31
Figura 8 – Saltos condicionais
Instrução Descrição Quando saltar
JNA, JBE Abaixo ou igual CF = 1 ou ZF = 1
JNB, JAE, JNC Não abaixo de CF = 0
JE, JZ Zero, igual ZF = 1
JNLE, JG Maior que SF = OF e ZF = 0
JGE, JNL Maior que ou igual a SF = OF
JO Excesso OF = 1
JS Sinal negativo SF = 1
JCXZ CX é zero CX = 0
JB, JNAE, JC Abaixo CF = 1
JNBE, JA Acima CF = 0 & ZF = 0
JNE, JNZ Não zero, não igual ZF = 0
JL, JNGE Menor que SF ≠ OF
JLE, JNG Menor que ou igual a SF ≠ OF ou ZF = 1
JNO Não excesso OF = 0
JNS Não negativo SF = 0
Fonte: Tanenbaum e Austin (2013, p. 557).
Linguagem de Montagem
32
RESUMINDO:
E então? Gostou do que lhe mostramos? Aprendeu mesmo
tudinho? Agora, só para termos certeza de que você
realmente entendeu o tema de estudo deste capítulo, vamos
resumir tudo o que vimos. Você deve ter aprendido que a
linguagem de montagem Assembly permite programar
utilizando as estruturas condicionais. As mesmas estruturas
condicionais usadas em linguagem de alto nível, mas em
linguagem de baixo nível. Quando utilizamos o recurso
condicional no Assembly, usamos os comandos de “pulo”
ou “desvio” para executar determinada instrução de acordo
com um critério. Os comandos JMP e JNE são alguns dos
mais usados quando utilizamos a estrutura condicional. O
comando CMP também é bastante usado para efetuar a
comparação dos dados no critério. Podemos classificar os
desvios em Assembly como condicional ou incondicional.
Linguagem de Montagem
33
Estruturas de repetição do Assembly
OBJETIVO:
Ao término deste capítulo, você será capaz usar estruturas
de repetição para otimização de programas em linguagem
de montagem. E então? Motivado para desenvolver essa
competência? Então, vamos lá. Avante!
A estrutura de repetição pode ser usada em linguagem e baixo nível.
Usamos a estrutura de repetição para executar comandos de acordo com
a quantidade de vezes especificada no problema.
Figura 9 – Repetição
Fonte: Freepik
A seguir temos uma estrutura de repetição em linguagem de alto
nível C++.
void test(){
int var=0;
while (varem CX.
Quando usamos os comandos MOVS, LODS e STOS, podemos
fazer uso do prefixo REP. O prefixo REP decrementa o registrador CX e
repete a instrução string enquanto CX ≠ 0.
O comando REPZ faz o decrement em CX (o registrador CX-, porém
não afeta os flags). Em seguida, repete toda a instrução string, enquanto
CX for diferente (≠) de 0 e ZF for igual à 1 (=1). Utilizamos o comando REPNZ
para decrementar CX (contador), não afetando os flags e provocando uma
Linguagem de Montagem
38
repetição do comando string enquanto CX for diferente (≠) de 0 e ZF for
igual (=) a 0.
Formato:
REP instrução_string
REPZ instrução_string
REPNZ instrução_string
Exemplo: Considere que se queira preencher um bloco de memória,
com 512 bytes de extensão, com o valor inicial 20H (ROCHA, 2021, p. 35):
CLD ; Reseta o flag de direção
MOV CX,200 ; Contador em CX
MOV DI,1000 ; Endereça a área de memória
MOV AX,2020 ; Dados em AH e AL
REP STOSW; Preenche 200 palavras a partir de ES:1000 (ES:DI)
Operações de laço e repetição
A instrução LOOP decrementa o registrador CX e salta para
trás até o rótulo indicado se o resultado for positivo. As
instruções LOOPZ, LOOPE, LOOPNZ e LOOPNE também
testam o flag de zero para ver se o laço deve ser abortado
antes de CX ser 0. (TANENBAUM; AUSTIN, 2013, p. 555)
VOCÊ SABIA?
Uma instrução em linguagem de montagem tem o
comprimento médio de instrução de 2,5 bytes e, por este
motivo, a instrução LOOP só pode saltar para trás no
máximo 50 instruções.
Podemos também usar as instruções REPNZ, REPZ e REP para
realizar alguns mecanismos especiais relacionados a laços de instruções
em cadeia.
Linguagem de Montagem
39
VOCÊ SABIA?
O comprimento da cadeia está armazenado no registrador
CX (TANENBAUM; AUSTIN, 2013, p. 555).
Executando um loop no EMU8086
Outra estrutura de programação muito utilizada são os laços de
repetição (looping), ou malhas de repetição, cuja característica operacional
é a capacidade de executar um trecho de programa por determinado
número de vezes. Normalmente, um laço de repetição é estabelecido
com uso da instrução LOOP. O laço de repetição executa uma ação
determinando o número de vezes.
IMPORTANTE:
As instruções de repetição ou de laço, como o LOOP, fazem
uso do valor que está no registrador CX para a operação
do contador de passos. O valor é sempre subtraído do
registrador geral CX.
Para exemplificar operações com laços de repetição, considere
um programa que apresente cinco vezes na tela do monitor de vídeo a
mensagem Alo Mundo!, conforme indicado a seguir.
Figura 11 – Estrutura de loop no EMU8086
org 100h
.MODEL small
.STACK 512d
.DATA
msg DB ‘Alo Mundo’, 0Dh, 0Ah, 24h
.CODE
LEA DX,msg
MOV CX, 5d
MOV AH, 09h
laco:
INT 021h
LOOP laco
INT 20h
ret
Fonte: EMU8086 (2022, n.p.).
Linguagem de Montagem
40
Figura 12 – Estrutura de loop no EMU8086 – Execução (loop de 5)
Fonte: EMU8086 (2022, n.p).
Os valores 0Dh, 0Ah, 24h após a definição da mensagem são
responsáveis pela definição dos códigos de controle para apresentação
de um string.
A definição da instrução MOV CX, 5d estabelece para o registrador
geral CX o valor decimal 5, que será automaticamente decrementado em
1 toda vez que a instrução LOOP for executada.
No código que se segue, substituímos a linha “MOV CX, 5d” pela
instrução “MOV CX, 8d”. Podemos perceber a execução da mensagem
“Alo Mundo” 8 vezes.
Linguagem de Montagem
41
Figura 13: Estrutura de loop no EMU8086
org 100h
.MODEL small
.STACK 512d
.DATA
msg DB ‘Alo Mundo’, 0Dh, 0Ah, 24h
.CODE
LEA DX,msg
MOV CX, 8d
MOV AH, 09h
laco:
INT 021h
LOOP laco
INT 20h
ret
Fonte: EMU8086 (2022, n.p.).
Na figura que se segue, podemos ver a execução do código anterior
no programa EMU8086.
Figura 14 – Estrutura de loop no EMU8086 – Execução (loop de 8)
Fonte: EMU8086 (2022, n.p.).
Linguagem de Montagem
42
RESUMINDO:
E então? Gostou do que lhe mostramos? Aprendeu mesmo
tudinho? Agora, só para termos certeza de que você
realmente entendeu o tema de estudo deste capítulo,
vamos resumir tudo o que vimos. Você deve ter aprendido
que podemos utilizar as estruturas de repetição também
na linguagem de montagem Assembly. Assim como as
estruturas condicionais, as estruturas de repetição podem
ser usadas em linguagem de baixo nível. As estruturas
de repetição em linguagem de montagem possuem
comandos específicos, como os comandos LOOP e REP,
que possuem “variantes” de acordo com o tipo de repetição
de acordo com o tipo de dados que está sendo manipulado
na estrutura de repetição. Alguns programas podem ser
usados para facilitar a programação em Assembly para
futuras edições e incrementos em programas .asm, e um
desses programas é o EMU8086.
Linguagem de Montagem
43
Programação dos chips em Assembly
OBJETIVO:
Ao término deste capítulo, você será capaz de aplicar a
programação em chips. E então? Motivado para desenvolver
essa competência? Então, vamos lá. Avante!
Temos componentes no padrão x86 que se integram a outros
componentes e examinam a configuração da placa-mãe e o conjunto de
chips que a CPU utiliza. Componentes como memória, portas de E/S e
interfaces de dispositivos comuns são dispositivos comuns que utilizam
o padrão x86. Por isso, veremos como os programas em linguagem
Assembly podem realizar E/S em diferentes níveis e ter acesso ao
hardware do sistema, acesso ao firmware e fazer chamadas de funções
no sistema operacional.
Figura 13 – Processadores
Fonte: Freepik
Placa-mãe
A placa-mãe é a base, mas alguns dizem que é “o coração” do
microcomputador. A placa-mãe é uma placa plana de circuito em que são
colocados os seguintes componentes: CPU do computador, processadores
Linguagem de Montagem
44
de suporte (chipset), memória principal, conectores de entrada-saída,
conectores da fonte de alimentação e slots de expansão. Os vários
componentes estão ligados a outros por um barramento, um conjunto de
fios gravados diretamente na placa-mãe. Dezenas de placas-mãe estão
disponíveis no mercado de PCs, variando em recursos de expansão,
componentes integrados e rapidez. Os seguintes componentes são
tradicionalmente encontrados em placas-mãe de PC (IRVINE, 2007, p. 48):
• Soquete de CPU, em que os soquetes podem ser de diferentes
formas e tamanhos, variando o tipo de processador.
• Slots de memória (podendo ser SIMM ou DIMM, por exemplo) que
possuem pequenas placas de memória plug-in.
• Chips de computador – BIOS, que é um sistema básico de entrada
e saída, podendo manter o software do sistema.
• RAM CMOS, com uma pequena bateria circular para mantê-lo
ligado.
• Conectores para dispositivos de armazenamento em massa, como
discos rígidos e CD-ROMs.
• Conectores USB, voltados para dispositivos externos.
• Portas para mouse e teclado.
• Alguns conectores de barramento padrão PCI para placas de som,
placas gráficas, placas de aquisição de dados e outros dispositivos
de saída de entrada.
Os seguintes componentes são opcionais:
• Processador para som.
• Conectores de dispositivos no padrão paralelos e seriais.
• Elaborado pela autora com base emr de rede integrado.
• Conector de barramento padrão AGP para uma placa de vídeo de
alta velocidade.
Alguns processos são importantes no sistema, por exemplo:
Linguagem de Montagem
45
• A Unidade de Ponto Flutuante (FPU) lida com cálculos de ponto
flutuante e inteiros estendidos.
• O Gerador de Relógio 8284/82C284, conhecido simplesmente
como relógio, oscila a uma velocidade constante.
IMPORTANTE:
O gerador de clock sincroniza a CPU e o resto do
computador.
• O Controlador de Interrupção Programável (PIC) 8259A lida com
interrupções externas de dispositivos de hardware, como teclado,
relógio do sistema e unidades de disco. Esses dispositivos
interrompem a CPU e fazem-na processar seus pedidos
imediatamente.
• O temporizador ou contador de intervalo é programável e atualiza
a data e o relógiodo sistema e controla o alto-falante. Também é
responsável por atualizar constantemente a memória porque os
chips de memória RAM podem “lembrar” seus dados por apenas
alguns milissegundos.
• A porta do tipo paralela e programável 8255 transfere dados de e para
o computador usando a interface de porta paralela IEEE. Essa porta
é comumente usada para impressoras, porém, pode ser usada para
outros dispositivos de entrada-saída também (IRVINE, 2007, p. 48).
Chipset
Em uma placa-mãe de computador, podemos encontrar os chipsets que
são uma coleção de chips de processador projetados para trabalhar juntos em
um tipo de placa-mãe. Podemos encontrar diferentes chipsets com recursos
que aumentam o poder de processamento ou reduzem o consumo de energia.
Um exemplo interessante é o chipset Intel P965 Express, que pode ser usado em
PCs desktop, que utilizam processador Intel Core 2 Duo ou Pentium D.
Algumas características são:
Linguagem de Montagem
46
• O componente Intel Fast Memory Access utiliza um hub controlador
de memória (MCH) atualizado. Ele pode acessar memória DDR2 de
canal duplo, a uma velocidade de clock de 800 MHz.
• Temos o hub controlador de E/S (Intel ICH8/R/DH), que utiliza
tecnologia Intel Matrix Storage (MST) para suportar seis dispositivos
Serial ATA (unidades de disco).
• Suporte para 10 portas USB, com seis slots PCI Express, rede,
tecnologia Intel Quiet System.
• Um chip de áudio de alta definição para oferecer recursos de som
digital.
• Um diagrama pode ser visto na figura adiante. Os fabricantes de
placas-mãe constroem produtos em volta de chipsets específicos.
Por exemplo, a placa-mãe P5B-E P965 da Asus Corporation usa o
P965 chipset (IRVINE, 2007, p. 49).
Figura 14 – P965
Intel Core 2 Duo
Processor
Intel Fast Memory
Access
PCI Express x16
Graphics
10 Hi-Speed USB 2.0
Ports; Dual EHQ; USB
Disable
Intel High Definition
Audio
Intel Quiet System
Technology
6 Serial ATA Ports
DDR2
DDR2
BIOS/Firmware
6 PCI Express x1
Intel Matrix Storage
Technology
Intel GbE LAN
P965
MCH
P965
ICHB
8,5 GB/s
8
GB/s
60
MB/s
LPC or SPI
Optional
2 GB/s DMI
500
MB/s
each x1
12,8
GB/s
3
GB/s
each
Fonte: Irvine (2007, p. 49).
Linguagem de Montagem
47
Programando os chips
Para programar nosso código hexa, como codificado no arquivo
.HEX, no AVR, um software programador é necessário. Esse software lê
o arquivo .HEX e transfere o seu conteúdo, seja bit a bit (programação
serial), seja byte a byte (programação paralela), para a memória flash do
AVR. Iniciamos o software de programação e carregamos os arquivos hex
que acabamos de gerar.
Figura 15 – AVR
Fonte: Schmidt (2003, online).
Em nosso exemplo, a tela seria semelhante à apresentada.
O programa ISP.exe é muito conhecido e histórico, porém, não
mais distribuído pela ATMEL. Outros softwares programadores são
semelhantes.
VOCÊ SABIA?
Podemos usar Elaborado pela autora com base emres em
formato USB para enviar o código .HEX para o chipset.
Esse software pode gravar o código no local designado no chip.
Temos precondições necessárias para fazer isso e várias razões possíveis
para uma falta.
Linguagem de Montagem
48
Hardware de programação e alternativas de software apropriadas
para diferentes sistemas operacionais estão acessíveis na internet.
Podemos usar como exemplo um programa para porta paralela ou serial,
como PonyProg2000.
No AVR, após o primeiro passo ser executado, a janela do
processador ficaria como na figura que se segue.
Figura 16 – Processador
Fonte: Schmidt (2003, online).
O contador de programa (Program Counter), mostrado
na janela do processador, está no passo 1, o contador de
ciclo em 2 (RJMP precisa de dois ciclos para executar).
Com clock de 1 MHz, dois microssegundos foram gastos,
os flags e registradores não foram alterados. A janela
com o arquivo texto fonte mostra um ponteiro no próximo
comando a ser executado. (SCHMIDT, 2003, online)
Figura 17 – Simulador
Fonte: Schmidt (2003, online).
Linguagem de Montagem
49
Podemos pressionar a tecla F11 novamente para executar a nova
instrução, o registrador “mp” (que é R16) ficará será o valor 0xFF. Na janela
do lado direito (onde mostra a mudança as alterações nos registradores),
se destacará o ajuste realizado pela linha de código.
Podemos observar, na figura seguinte, que o novo valor de R16 está
na cor vermelha (no lado direito da imagem). Podemos efetuar ajustes
e alterações no registrador sempre que necessário e verificar os dados
gerados.
Figura 18 – Novo valor no registrador R16
Fonte: Schmidt (2003, online).
Nesse momento,
[...]a saída é direcionada ao registrador da porta B. Para
mostrar, abrimos uma nova janela de visualização de E/S e
selecionamos porta B. A imagem deve ser como a seguir. O
registrador de direção de dados na janela de visualização
de E/S na porta B agora mostra o novo valor. Os valores
podem ser alterados manualmente, se desejado, pino a
pino.Os próximos dois passos são simulados usando F11.
Eles não serão mostrados aqui. Setando as portas de saída
para nível um com a instrução
LDI mp, 0xFF e OUT PORTB, mp resulta na seguinte figura
na visualização de E/S. Agora todos os bits de saída da
porta estão em nível um, a visualização de E/S mostra isso.
(SCHMIDT, 2003, online)
Linguagem de Montagem
50
Figura 19 – PORTB
Fonte: Schmidt (2003, online).
“O simulador é capaz de muito mais, devendo, portanto, ser utilizado
extensivamente nos casos de erro de projeto” (SCHMIDT, 2003, online).
Após efetuar a programação e a simulação, transferimos o arquivo
de extensão .HEX ou .BIN para o chipset por meio do Elaborado pela
autora com base emr USB específico para o componente.
No EMU8086, ao compilar o programa, podemos gerar um arquivo
binário para ser transferido para o chip.
Figura 20 – Salvando arquivo no programa EMU8086
Fonte: Programa EMU8086 (2022, n.p.).
Linguagem de Montagem
51
RESUMINDO:
E então? Gostou do que lhe mostramos? Aprendeu mesmo
tudinho? Agora, só para termos certeza de que você
realmente entendeu o tema de estudo deste capítulo,
vamos resumir tudo o que vimos. Você deve ter aprendido
que a linguagem de programação Assembly permite
fazer a gravação direto no equipamento de hardware.
Para isso, utilizamos programas específicos de acordo
com o hardware que estamos manipulando. Cada tipo
de processador tem um programa específico para fazer a
gravação no equipamento. Os processadores de modelo
AVR, por exemplo, utilizam um programa específico para
gravar os dados no equipamento. Para transferir os dados
do programa para o chip, podemos utilizar Elaborado
pela autora com base emres em que uma ponta é USB
(que faz a ligação com a máquina) e a outra ponta liga-
se ao processador. Para fazer testes de programação e
simulação, podemos usar modelos de placas específicas
para esse fim.
Linguagem de Montagem
52
REFERÊNCIAS
IRVINE, K. R. Assembly Language for x86 processors. 2007.
Disponível em: www.bsit.zxq.net. Acesso em: 20 abr. 2022.
KUNDRO, D. Estruturas de controle de fluxo em código Assembly.
Welivesecurity, 2020. Disponível em: https://www.welivesecurity.com/
br/2020/05/04/estruturas-de-controle-de-fluxo-em-codigo-assembly/.
Acesso em: 05 maio 2022.
PROGRAMA EMU8086. 2022. Disponível em: https://emu8086-
microprocessor-emulator.softonic.com.br/. Acesso em: 26 maio 2022.
TANENBAUM, A.; AUSTIN, T. Organização estruturada de
computadores. 6. ed. São Paulo: Pearson, 2013.
ROCHA, O. Apostila das instruções Assembler do 8088. 2021.
Disponível em: https://docero.com.br/doc/105180v. Acesso em: 20 abr.
2022.
SCHMIDT, G. Introdução para o iniciante à Linguagem Assembly
dos microprocessadores ATMEL-AVR. 2003. Disponível em: www.avr-
asm-tutorial.net. Acesso em: 20 abr. 2022.
STALLINGS, W. Arquitetura e organização de computadores.
8. ed. São Paulo: Pearson, 2002. Disponível em: http://www.telecom.uff.
br/orgarqcomp/arq/arquitetura-e-organizacao-computadores-8a.pdf.Acesso em: 07 abr. 2022.
TANENBAUM, A.; AUSTIN, T. Organização estruturada de
computadores. 6. ed. São Paulo: Pearson, 2013.
Linguagem de Montagem
https://www.welivesecurity.com/br/2020/05/04/estruturas-de-controle-de-fluxo-em-codigo-assembly/
https://www.welivesecurity.com/br/2020/05/04/estruturas-de-controle-de-fluxo-em-codigo-assembly/
https://emu8086-microprocessor-emulator.softonic.com.br/
https://emu8086-microprocessor-emulator.softonic.com.br/
https://docero.com.br/doc/105180v
http://www.telecom.uff.br/orgarqcomp/arq/arquitetura-e-organizacao-computadores-8a.pdf
http://www.telecom.uff.br/orgarqcomp/arq/arquitetura-e-organizacao-computadores-8a.pdf