Você está na página 1de 32

Introdução à Programação

Assembly

Assembly
• Em aulas anteriores foi visto que um
programa de computador é constituído de
uma sequência de instruções de máquina.
• Foi visto também que estas instruções são
constituídas de uma sequência de bits
agrupadas por campos.
• Sendo assim, um programa de
computador tem a forma apresentada no
slide seguinte.

1
Assembly

Assembly
• Mesmo tendo apenas poucas instruções, o programa
mostrado no slide anterior é um tanto confuso.
• O que dizer de programas com centenas de
instruções?
• Com o objetivo de tornar os programas mais legíveis,
cada instrução destes passou a ser representada por
um conjunto de letras chamado mnemônico.
• O conjunto de mnemônicos relativos a uma
determinada máquina forma a sua linguagem
assembly.
• O mesmo programa do slide anterior é mostrado no
slide seguinte com essa nova representação.

2
Assembly

Assembly
• É possível concluir que esta última
representação é mais legível do que a primeira.
• Embora o programa constituído de mnemônicos
seja mais legível para nós humanos, não é
interpretável diretamente pelos processadores,
pois estes somente decodificam instruções de
máquina.
• Por isso foi desenvolvido um programa de
computador denominado assembler, o qual
converte cada mnemônico, ou instrução
assembly, na sua correspondente instrução de
máquina.

3
Diretivas de compilação
• Sendo um compilador, o assembler
necessita de algumas diretivas de
compilação.
• Estas diretivas fornecem parâmetros para
o compilador durante a compilação.

Principais Diretivas Utilizadas pelo


Compilador Assembler
• Org: indica o endereço da memória de programa
onde a instrução seguinte a ela começa a ser
armazenada.

• Exemplo: org 0000h;


• mov p1, #15;

• Neste exemplo, a instrução mov é armazenada a


partir do endereço 0 da memória de programa. As
demais instruções são armazenadas nos endereços
subsequentes aos ocupados por esta.

4
Principais Diretivas Utilizadas pelo
Compilador Assembler
• Dataorg: função análoga à org, utilizada para
indicar o endereço inicial da memória de dados
onde as variáveis começam a ser armazenadas.

• Exemplo: dataorg 10
• var1 DS 1
• var2 DS 1

• Neste exemplo, var1 representa o endereço 10


da memória de dados, enquanto var2
representa o endereço 11.

Principais Diretivas Utilizadas pelo


Compilador Assembler
• Ds: reserva uma quantidade determinada
de bytes na memória de dados.

• Exemplo: dataorg 12
• var1 DS 5

• Neste exemplo são reservados 5 bytes na


memória de dados, a partir do endereço
12, endereço este representado por var1.

5
Principais Diretivas Utilizadas pelo
Compilador Assembler
• Equ: utilizada para atribuir um valor
numérico a um nome.

• Exemplo: onze equ 11d;

• Neste exemplo, sempre que o nome onze


for referenciado, o programa entende que
o valor 11 deve ser utilizado.

Principais Diretivas Utilizadas pelo


Compilador Assembler
• Set: semelhante a equ, porém ao contrário
desta última, set permite que um mesmo
nome seja utilizado para armazenar
diferentes valores ao longo da execução
do programa.

6
Principais Diretivas Utilizadas pelo
Compilador Assembler
• Data: utilizada para atribuir um nome ao
endereço de uma palavra na memória de
dados.

• Exemplo: var5 data 13

• Neste exemplo, o endereço 13 da


memória de dados é atribuído ao nome
var5.

Principais Diretivas Utilizadas pelo


Compilador Assembler
• Bit: utilizada para atribuir um nome ao
endereço de um bit na memória de dados.

7
Principais Diretivas Utilizadas pelo
Compilador Assembler
• Include: utilizada para incluir o código
contido em um outro arquivo no código
corrente.

• Exemplos: Include “filename.ext”


• $filename.ext

Principais Diretivas Utilizadas pelo


Compilador Assembler
• Às vezes é necessário armazenar dados que não
podem ser perdidos quando a fonte de alimentação é
retirada do processador.
• A memória de programa pode ser usada para essa
finalidade.
• Para isso utiliza-se a diretiva DB.

• Exemplo:
• Label1: DB ‘hello’, 15, 2

• Nesse exemplo, cada um dos caracteres da palavra


hello e cada um dos números são armazenados em uma
posição da memória de programa, iniciando por h.

8
Principais Diretivas Utilizadas pelo
Compilador Assembler
• End: utilizada para informar ao compilador
que as instruções assembly terminaram.

Operadores
• Além das diretivas, alguns operadores podem
ser utilizados durante a compilação de um
programa.
• Dois destes operadores são HIGH e LOW.
• HIGH retorna o byte de mais alta ordem de uma
palavra de 2 bytes e LOW retorna o byte de
mais baixa ordem dessa palavra.

• Exemplo:
• D_byte equ 1245H
• MOV R3, #HIGH D_byte

9
Operadores
• No exemplo do slide anterior, o valor 124516 é
colocado em D_byte.
• Em seguida, o valor armazenado no byte mais
alto de D_byte (1216) é movido para o
registrador R3.
• O caractere H escrito no final do número 1245
informa que este é um valor hexadecimal.
• Outros caracteres indicadores de tipo são D
(decimal) e B (binário).

Comentários
• Em assembly do 8051, um comentário é
iniciado com o caractere ; e se estende
até o final da linha.
• O caractere ; deve estar separado, por um
ou mais espaços, dos caracteres da
instrução que o antecede.

10
Maiúsculo e Minúsculo
• A linguagem assembly do 8051 não faz
distinção entre as letras maiúsculas e
minúsculas.
• Sendo assim, END, End e end
representam a mesma coisa.

Técnicas Para Tradução de


Algoritmos
• Durante a tradução de um código escrito em
alto nível para a linguagem de máquina, é
preciso ter em mente que, em geral, as
instruções lógicas e aritméticas de máquina
somente executam uma operação simples de
cada vez.
• Sendo assim, a instrução de C,
• A=B+C+D;
• deve ser subdivida em uma sequência de
somas simples antes de ser traduzida para a
linguagem assembly, conforme descrição
seguinte.

11
Técnicas Para Tradução de
Operações Aritméticas
• A=B+C
• A=A+D

• Observe que as duas somas simultâneas


foram substituídas por duas somas
sequenciais.
• Neste exemplo admite-se que estas
instruções sejam armazenadas na
memória na ordem em que estão escritas.

Técnicas Para Tradução de


Operações Aritméticas
• Tendo em vista que um dos operandos precisa
estar no registrador acumulador (Acc) durante
as operações aritméticas realizadas no 8051, a
soma anterior é traduzida para assembly como
mostrado a seguir.

• MOV Acc, B
• ADD Acc, C
• ADD Acc, D

• Onde: B, C e D são endereços de memória.

12
Técnicas Para Tradução de
Operações Aritméticas
• Deve ser observado que no 8051 o operando de
destino é aquele escrito mais próximo da
instrução.
• Sendo assim, no fragmento de código anterior,
a instrução
• ADD Acc, C
• não poderia ser escrita da forma
• ADD C, Acc
• pois o resultado das operações aritméticas
sempre são colocados automaticamente no
registrador Acc do 8051.

Técnicas Para Tradução de


Operações Aritméticas
• Deve ser lembrado que no 8051 o registrador
acumulador também é referenciado pela letra A,
o fragmento de código da soma anterior
também pode ser escrito do modo seguinte.

• MOV A, B
• ADD A, C
• ADD A, D

• Onde: B, C e D são endereços de memória.

13
Técnicas para Tradução da
Estrutura de Repetição While
• Nos próximos slides, as palavras desvio e salto são
utilizadas para especificar que a próxima instrução a ser
executada não é aquela armazenada no endereço
seguinte ao da que se encontra em execução.
• No programa armazenado na memória apresentada no
slide seguinte, o mais frequente é a instrução do
endereço 1 (instrução 2) ser executada logo após a
execução da instrução do endereço 0 (instrução 1).
• Entretanto, a instrução 1 pode instruir o processador a
buscar e executar a instrução do endereço 19 (instrução
20), por exemplo. Neste caso, o mais frequente não
ocorre, ou seja, a instrução 2 não é executada logo após
a execução da instrução 1.

Técnicas para Tradução da


Estrutura de Repetição While

14
Técnicas para Tradução da
Estrutura de Repetição While
• A instrução que possui a capacidade de ordenar
o processador para executar outra instrução
diferente daquela que lhe sucede é chamada de
instrução de desvio (instrução 1 do slide
anterior).
• A ação de executar a instrução do endereço 19
logo após a execução da instrução do endereço
0, por exemplo, é conhecida como “salto” ou
“desvio”. Neste exemplo, se não ocorresse o
salto, a instrução do endereço 1 seria executada
logo após a execução desta do endereço 0.

Técnicas para Tradução da


Estrutura de Repetição While
• Para traduzir o código da estrutura while
de C para o pseudocódigo de máquina é
necessária uma instrução de desvio
incondicional e uma instrução de desvio
condicional, ordenadas conforme o
exemplo a seguir.

15
Técnicas para Tradução da
Estrutura de Repetição While
• Exemplo:
while(Bit3_P1 == 1)
{
R2 = R2 + 1;
R3 = R3 – 1;
}

Técnicas para Tradução da


Estrutura de Repetição While
• Neste exemplo, enquanto a variável
Bit3_P1 for igual a 1, a variável R2 deve
ser incrementada e a variável R3 deve ser
decrementada. Sendo assim, o bloco de
execução é composto de duas instruções.
• Esta estrutura é escrita em pseudocódigo
de máquina do seguinte modo.

16
Técnicas para Tradução da
Estrutura de Repetição While
• 0: instrução 1
• 1: …

• 10: …
• 11: instrução 12
• 12: Salte para o endereço 15
• 13: incremente R2
• 14: decremente R3
• 15: Salte para o endereço 13, se Bit3_P1 é igual a 1
• 16: Instrução 17
• 17: …

Onde: 0: 1: … 17: representam endereços de memória.

Técnicas para Tradução da


Estrutura de Repetição While
• No último slide, o programa começa a ser executado no endereço 0
e prossegue até o endereço 12.
• Quando chega neste endereço, salta para o endereço 15 e verifica
se o valor de Bit3_P1 é igual a 1.
• Caso a verificação seja verdadeira, salta de volta para o endereço
13 e executa o bloco interior do while. Em seguida, volta a verificar
o valor de Bit3_P1 e salta para o endereço 13, até que a verificação
resulte em um resultado falso.
• Caso a verificação produza um resultado falso, a instrução de
desvio condicional do endereço 15 não promove o salto para o
endereço 13, o que leva o processador a buscar a instrução
seguinte (instrução do endereço 16) e prossegue com a execução
do restante do programa.

17
Técnicas para Tradução da
Estrutura de Repetição While
• Em assembly do 8051, o while anterior
fica:

Técnicas para Tradução da


Estrutura de Repetição While
• Observe que no programa anterior, o endereço
de desvio da instrução de desvio condicional é
14 e não 13.
• Isso é necessário porque existe instrução no
8051 que ocupa mais de um endereço de
memória, como é o caso da instrução de desvio
incondicional do endereço 12.
• Observe também a letra D após o valor do
endereço, utilizada para informar que o
endereço é especificado em decimal.

18
Loop Infinito
• Nos processos reais, as portas de entrada do
microcontrolador devem ser lidas
continuamente, com o objetivo de detectar
qualquer variação no estado destas.
• Isso é necessário porque os processos são
dinâmicos: pressão muda com o tempo, assim
como nível, etc.
• Sendo assim, quando a execução do programa
chega na última linha, o programa deve ser
reiniciado.
• Isto é alcançado por meio de um loop infinito.

Loop Infinito
• O loop infinito é obtido a partir da
implementação do while, removendo a
instrução de desvio incondicional deste
último e substituindo a instrução de desvio
condicional por outra de desvio
incondicional com endereço de desvio
igual ao do início do programa.

19
Loop Infinito
• Exemplo de loop infinito.

Neste exemplo, toda vez que a execução chega na última linha, retorna para
a primeira, repetindo a execução de todo o programa.

Técnicas para Tradução da


Estrutura de seleção IF-ELSE
• Para traduzir o código da estrutura IF-
ELSE de C para o pseudocódigo de
máquina é necessária uma instrução de
desvio incondicional e uma instrução de
desvio condicional, ordenadas conforme o
exemplo a seguir.

20
Técnicas para Tradução da
Estrutura de seleção IF-ELSE
• If (Bit3_P1 == 1)
• {
• R1 = R1 + 1;
• R2 = R2 + 1;
• }
• else
• {
• R1 = R1 – 1;
• R2 = R2 – 1;
• }

Técnicas para Tradução da


Estrutura de seleção IF-ELSE
• Neste exemplo, caso a variável Bit3_P1
seja igual a 1, as variáveis R1 e R2 devem
ser incrementadas. Porém, em caso
contrário, estas devem ser
decrementadas.
• A estrutura correspondente em
pseudocódigo de máquina é escrita do
seguinte modo.

21
Técnicas para Tradução da
Estrutura de seleção IF-ELSE
• 0: Salte para o endereço 4, se Bit3_P1 é igual a 1
• 1: Decremente R1
• 2: Decremente R2
• 3: Salte para o endereço 6
• 4: Incremente R1
• 5: Incremente R2
• 6: Fim

Onde: 0: 1: … 6: representam endereços de memória.

Técnicas para Tradução da


Estrutura de seleção IF-ELSE
• Como pode ser observado no slide anterior, a
estrutura do IF em assembly começa por uma
instrução de desvio condicional, seguida do
bloco que deve ser executado se a verificação
do IF for falsa (o bloco ELSE).
• Em seguida vem uma instrução de desvio
incondicional, seguida do bloco que deve ser
executado se a verificação do IF for verdadeira.
• Observe que o endereço de desvio da instrução
de desvio condicional é igual ao da primeira
instrução do bloco mencionado por último.

22
Técnicas para Tradução da
Estrutura de seleção IF-ELSE
• Em assembly do 8051, o if-else anterior
fica:

Técnicas para Tradução da


Estrutura de seleção IF-ELSE
• Observe que no programa anterior, o
endereço de desvio das instruções de
desvio são diferentes daqueles previstos
no pseudocódigo de máquina.
• Isto ocorre porque algumas instruções do
8051 ocupam mais de um endereço de
memória.

23
Técnicas para Tradução da
Estrutura de seleção IF-ELSE
• Existe outra técnica para descrever estruturas
IF-ELSE que geralmente utiliza menos
instruções de máquina, especialmente se a
estrutura for apenas IF.
• Embora essa técnica possa utilizar menos
instruções do que a apresentada anteriormente,
a sua sintaxe é um pouco mais difícil de ser
compreendida.
• Tal técnica é apresentada por meio do mesmo
exemplo utilizado na outra.

Técnicas para Tradução da


Estrutura de seleção IF-ELSE
• If (Bit3_P1 == 1)
• {
• R1 = R1 + 1;
• R2 = R2 + 1;
• }
• else
• {
• R1 = R1 – 1;
• R2 = R2 – 1;
• }

24
Técnicas para Tradução da
Estrutura de seleção IF-ELSE
• Pseudocódigo de máquina correspondente

• 0: Salte para o endereço 4, se Bit3_P1 é igual a 0


• 1: Incremente R1
• 2: Incremente R2
• 3: Salte para o endereço 6
• 4: Decremente R1
• 5: Decremente R2
• 6: Fim

Onde: 0: 1: … 6: representam endereços de memória.

Técnicas para Tradução da


Estrutura de seleção IF-ELSE
• Como pode ser observado no slide anterior, a
estrutura do IF em assembly começa por uma
instrução de desvio condicional, seguida do
bloco que deve ser executado se a verificação
do IF for verdadeira.
• Em seguida vem uma instrução de desvio
incondicional, seguida do bloco que deve ser
executado se a verificação do IF for falsa (o
bloco do ELSE).
• Observe que o endereço de desvio da instrução
de desvio condicional é igual a este da primeira
instrução do bloco ELSE.

25
Técnicas para Tradução da
Estrutura de seleção IF-ELSE
• Nesta última técnica, a verificação da instrução de
desvio condicional é sempre contrária daquela
verificada no IF de C. Por exemplo: caso seja
verificado em C se A ≥ B, em linguagem de máquina
verifica se A < B; caso seja verificado em C se A = B,
em linguagem de máquina verifica se A ≠ B; etc.
• No último exemplo, em C foi verificado se o
valor de Bit3_P1 é igual a 1, enquanto na
instrução de desvio condicional foi verificado se
Bit3_P1 é igual a 0.

Técnicas para Tradução da


Estrutura de seleção IF-ELSE
• Em assembly do 8051, o if-else anterior
fica:

26
Técnicas para Tradução da
Estrutura de seleção IF-ELSE
• Observe que no programa anterior, o
endereço de desvio das instruções de
desvio são diferentes daqueles previstos
no pseudocódigo de máquina.
• Isto ocorre porque algumas instruções do
8051 ocupam mais de um endereço de
memória.

Label
• Foi visto que as instruções de desvio
condicional e de desvio incondicional, utilizadas
na descrição das estruturas WHILE e IF-ELSE,
necessitam do endereço para onde o fluxo de
execução é desviado.
• A determinação de tais endereços é uma tarefa
um tanto tediosa.
• Sendo assim, o conceito de “label” foi idealizado
para livrar o programador da tarefa de calcular o
referido endereço, deixando tal tarefa a cargo
do software assembler.

27
Label
• Cada linha do código fonte pode conter
um “label” opcional.
• O label pode conter letras do alfabeto,
dígitos numéricos e o caractere underline.
Porém, o label deve iniciar com uma letra
do alfabeto e terminar com dois pontos (:).
• Um label pode conter muitos caracteres,
mas somente os primeiros 32 serão
reconhecidos pelo assembler.

Label
• Quando o assembler encontra um label,
tal como descrito no slide anterior,
armazena o endereço da primeira
instrução seguinte a este em uma tabela.
• Desse modo, em todas as instrução que
fazem referência ao referido label, o
assembler substitui este pelo seu
correspondente endereço, armazenado na
tabela mencionada.

28
Exemplo de aplicação do Label
• JB P1.3, 0012H
• ...
• MOV C, P3.4 ;Instrução armazenada no
endereço 0012H.

• JB P1.3, Label1
• ...
• Label1: MOV C, P3.4.

Exemplo de aplicação do Label


• No exemplo anterior, caso uma nova
instrução seja adicionada entre as
instruções JB e MOV, o endereço de
desvio da instrução JB deve ser alterado
no primeiro fragmento de código,
enquanto no segundo, nenhuma
modificação é necessária.

29
Implementação de Funções
Booleanas
• O 8051 tem instruções apropriadas para a
implementação de funções booleanas.
• Estas instruções realizam operações
lógicas sobre varáveis de um único bit.
Exemplo: dada a função booleana
P2.0 = P1.1(P1.0 + P1.3) extraída da
tabela-verdade relativa à solução de um
problema, implemente a com instruções
do 8051.

Implementação de Funções
Booleanas
• A função booleana anterior faz uma
operação OR entre os bits 0 e 3 da porta
1, sendo que o bit 3 aparece
complementado.
• Em seguida, é realizada uma operação
AND entre o resultado anterior e o bit 1 da
porta 1.
• O resultado final é movido para o bit 0 da
porta 2.

30
Implementação de Funções
Booleanas
• Em assembly do 8051, a implementação
fica:

Observe que nas operações lógicas realizadas sobre variáveis de um único bit, um
dos operandos deve estar no bit de carry out, representado em assembly pela letra
c.

Implementação de Funções
Booleanas
• Nos processos reais, as variáveis de
entrada devem ser verificadas
continuamente.
• Sendo assim, deve ser incluído um loop
no programa anterior.

31
Implementação de Funções
Booleanas
• Implementação com loop:

32

Você também pode gostar