Introdução à Organização de Computadores e Linguagens de …edson/disciplinas/mc404/2011... ·...
Transcript of Introdução à Organização de Computadores e Linguagens de …edson/disciplinas/mc404/2011... ·...
Introdução à Organização de Computadores eLinguagens de Montagem
Ricardo Anido© Draft date 25 de Março de 2011
Capítulo 3
O processador Faíska
Neste capítulo iniciaremos o estudo mais detalhado do repertório de instruções doprocessador Faíska, ilustrando com exemplos de trechos de programas o uso dasdiversas instruções. As instruções serão apresentadas usando um descritor no for-mato de uma tabela, como o mostrado na Figura 3, contendo o mnemônico da ins-trução em destaque em uma aba (MNE na figura), o nome, a sintaxe do comandocorrespondente em linguagem de montagem, a operação descrita de forma sucinta,e a codificação. O descritor inclui também um campo Flags, cujo significado seráintroduzido mais adiante, na Seção 3.2.1.
MNE
Nome da instrução
Sintaxe Operação Flags Codificação
31 0
Figura 3.1: Formato do descritor de instruções
As instruções serão apresentadas em grupos: transferência de dados, operaçõesaritméticas, instruções para controle de fluxo e operações lógicas.
3.1 Transferência de dados
Instruções de transferência de dados são as que permitem a transferência de dadosentre dois registradores do processador ou entre a memória e um registrador. Umexemplo de instrução de transferência de dados é a instrução “carrega registrador
7
8 CAPÍTULO 3. O PROCESSADOR FAÍSKA
com valor imediato”, que já foi introduzida no capítulo anterior. Nesta seção iremosestudar as outras instruções para transferência de dados do repertório de instruçõesdo Faíska.
3.1.1 Transferência entre registradores
Os operandos para instruções de transferência entre registradores são sempre doisregistradores: o registrador destino (operando mais à esquerda) e o registrador fonte(operando mais à direita). A operação executada é muito simples: o valor do regis-trador fonte é copiado para o registrador destino.
MOV
Carrega registrador com registrador
Sintaxe Operação Flags Codificação
mov rdest, rfonte rdest ← rfonte –31 0
00 rdest rfonte
Qualquer dos registradores de propósito geral do Faíska (r0 a r15) pode serusado como registrador destino ou fonte.
Exemplo 1
1 ; exemplo de instrução que copia o valor de um2 ; registrador para outro34 mov r1, r5 ; essa instrução é codificada usando uma5 ; palavra: 00000105h6
Antes
00 00 01 05 00100h
000fch
00104h
ff ff ff ffr1Memória
11 11 11 11r5
00 00 01 00ip
Processador
3.1. TRANSFERÊNCIA DE DADOS 9
Depois
00 00 01 05 00100h
000fch
00104h
11 11 11 11r1Memória
11 11 11 11r5
00 00 01 04ip
Processador
No exemplo acima são mostrados o estado antes e após a execução do trechode programa em linguagem de montagem, tanto do processador como da memória.Em todos os exemplos seguintes o mesmo esquema será utilizado. No processadorsão mostrados apenas os registradores importantes para entender a execução dotrecho de programa; os registradores e posições de memória que tiveram seus valoresalterados são mostrados em tom cinza após a execução.
3.1.2 Transferência da Memória para um registrador
O Faíska possui diferentes instruções para transferência de valores da memória paraum registrador, cada uma com modos de endereçamento distintos. As instruções detransferência da memória para registrador no Faíska utilizam três modos de endere-çamento: endereçamento imediato, endereçamento direto e endereçamento indiretopor registrador.
Carrega registrador com endereçamento imediato
No endereçamento imediato, o valor do operando faz parte do próprio código da ins-trução. Na instrução “carrega registrador com endereçamento imediato” o registra-dor destino é carregado com o valor do operando. E como o valor do operando écodificado na própria instrução, o valor carregado no registrador é sempre o mesmo.Em outras palavras, sempre que uma particular instrução desse tipo for executada,o registrador destino será carregado sempre com o mesmo valor. Dessa forma, essainstrução é utilizada para carregar um valor constante no registrador destino. Com-pare o efeito dessa instrução com a instrução “carrega registrador com endereça-mento direto”, introduzida no capítulo anterior. No endereçamento direto, o valorcarregado no registrador é o valor corrente de uma posição de memória. Como essevalor pode ser alterado pelo programa, uma mesma instrução “carrega registradorcom endereçamento direto” pode carregar diferentes valores no registrador destinoa cada vez que é executada.
O Faíska possui duas instruções de carga de registrador com endereçamentoimediato: uma em que a constante é codificada em apenas um byte e uma em que
10 CAPÍTULO 3. O PROCESSADOR FAÍSKA
SET
Carrega registrador com endereçamento imediato
Sintaxe Operação Flags Codificação
set rdest, expr8 rdest ← ext(imd8) –31 0
01 imd8 rdest
set rdest, expr32 rdest ← imd32 –
31 0
02 rdest
31 0
imd32
a constante é codificada em 32 bits. No caso em que a constante é codificada em 32bits, a instrução ocupa duas palavras. Para constantes que podem ser representadasem 8 bits, a instrução utiliza o campo imd8 para armazenar a constante como uminteiro com sinal em complemento de dois. Assim, esta forma só permite carregarconstantes entre−128 e 127. Como veremos, na programação em linguagem de mon-tagem muitas vezes utilizamos constantes dentro desse intervalo, o que nos permiteutilizar a forma mais econômica com bastante freqüência. É importante notar quetodos os 32 bits do registrador destino são carregados pela instrução set, mesmo nasua forma mais curta. Nesse caso, quando um valor imd8 positivo é carregado emum registrador, os 24 bits mais significativos do registrador são zerados. Quando ocampo imd8 tem um valor negativo, os 24 bits mais significativos do registrador des-tino recebem o valor 1, de forma a fazer com que o registrador tenha o valor negativocorreto. Ou seja, o bit de sinal do operando imd8 é estendido para os bits mais signi-ficativos do registrador destino. O fato de que o bit de sinal de imd8 é estendido paracompor o valor de 32 bits é mostrado no campo operação do descritor pela expressãoext(imd8).
Note que na descrição da sintaxe do comando em linguagem de montagem apa-rece o termo expr8, que representa uma expressão inteira, que quando avaliada deveresultar em um inteiro de 8 bits com sinal.
Exemplo 2
1 ; exemplo de instrução de carga de registrador com valor2 ; constante (endereçamento imediato)34 set r3, -1 ; instrução é codificada em uma5 ; palavra: 01ff0300h6
3.1. TRANSFERÊNCIA DE DADOS 11
Antes
22 22 22 22r3
Memória
00 00 10 00ip01000h
01004h
01 ff 03 00
Processador
Depois
ff ff ff ffr3
Memória
00 00 10 04ip01000h
01004h
01 ff 03 00
Processador
Exemplo 3
1 ; outros exemplos de instrução de carga de registrador com2 ; endereçamento imediato, com uma constante que não pode ser3 ; representada em 8 bits.45 set r9, 400h ; um valor que não pode ser6 ; representado em 8 bits7 ; código da instrução ocupa8 ; duas palavras:9 ; primeira palavra 02000900h
10 ; segunda palavra 00000400h11 set r12, var1 ; carrega endereço de var112 ; código da instrução ocupa13 ; duas palavras:14 ; primeira palavra 02000c00h15 ; segunda palavra 00070000h16 ...1718 org 70000h1920 var1: ds 4 ; uma variável qualquer21 ; montada no endereço 70000h
12 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Antes
33 33 33 33r9
Memória
55 55 55 55r12
00 00 01 08ip
00110h
00114h
00108h
0010ch
02 00 0c 00
00 07 00 00
00 00 04 00
03 00 09 00
Processador
Depois
00 00 04 00r9
Memória
00 07 00 00r12
00 00 01 18ip
00110h
00114h
00108h
0010ch
02 00 0c 00
00 07 00 00
00 00 04 00
03 00 09 00
Processador
Note que na linha 11 do Exemplo 3, quando o montador avalia a expressãointeira composta pelo rótulo, o resultado é o endereço do rótulo, ou seja, o endereçoda variável associada àquele rótulo. É esse endereço que é montado na segundapalavra da instrução, e portanto é esse endereço que é carregado como novo valor doregistrador r12.
Carrega registrador com endereçamento direto
O endereçamento imediato só é útil para carregar o valor de uma constante em umregistrador. Para implementar o conceito de variáveis é necessário ler e escreverposições específicas da memória. Assim, uma variável (i, por exemplo) pode ser asso-ciada a uma determinada posição da memória (2000h, por exemplo). Toda vez que sequiser acessar uma variável, faz-se um acesso à posição de memória correspondente.
Uma maneira de acessar posições específicas é utilizar o chamado endereça-mento direto, em que a instrução contém o endereço da posição de memória quecontém o valor a ser acessado.
A instrução ld (abreviatura do inglês load) carrega o valor de um registradorcom o conteúdo de uma posição de memória, cujo endereço é dado na própria ins-trução. Note que na descrição da sintaxe do comando em linguagem de montagemaparece o termo expr32, que representa uma expressão inteira, que quando avaliadadeve resultar em um inteiro de 32 bits (sem sinal, já que representa um endereço),
3.1. TRANSFERÊNCIA DE DADOS 13
representada na codificação como imd32. No entanto, na maioria dos casos expr32 éna realidade apenas um rótulo, associado a uma variável. O montador monta nasegunda palavra da instrução o endereço associado ao rótulo.
LD
Carrega registrador com endereçamento direto
Sintaxe Operação Flags Codificação
ld rdest, expr32 rdest ← mem[imd32] –
31 0
03 rdest
31 0
imd32
Note que para executar uma instrução ld o processador faz três acessos à me-mória: um acesso no endereço do ip corrente, para a busca da primeira palavra dainstrução; outro acesso no endereço do ip corrente mais quatro, para a busca do en-dereço do operando (imd32, segunda palavra da instrução); e ainda outro acesso paraa busca do valor operando (no endereço retirado no segundo acesso).
Exemplo 4
1 ; exemplo de instrução carrega registrador com2 ; endereçamento direto34 ld r10, cont ; exemplo de instrução ld5 ; código da instrução ocupa6 ; duas palavras:7 ; primeira palavra 03000a00h8 ; segunda palavra 00002000h9 ...
1011 org 2000h12 cont: ds 4 ; uma variável qualquer13 ; montada no endereço 2000h
14 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Antes
22 22 22 22 02000h
0fffch
02004h
55 55 55 55r10
Memória
00 00 01 00ip
00100h
00104h00 00 20 00
03 00 0a 00
Processador
Depois
22 22 22 22 02000h
0fffch
02004h
22 22 22 22r10
Memória
00 00 01 08ip
00100h
00104h00 00 20 00
03 00 0a 00
Processador
Carrega registrador com endereçamento indireto por registrador
No modo de endereçamento “indireto por registrador” o endereço do operando é dadoem um registrador, ao invés de ser um valor constante, codificado na instrução, comono endereçamento direto. Na linguagem de montagem, utilizaremos para a instru-ção de carga de registrador com endereçamento indireto por registrador o mesmomnemônico ld já utilizado anteriormente, mas indicaremos o modo de endereça-mento distinto pela grafia do operando fonte. Enquanto na instrução ld com modode endereçamento direto o operando fonte é um rótulo (no caso geral, qualquer ex-pressão inteira), na instrução ld com modo de endereçamento indireto por registra-dor o operando fonte é o nome de um registrador entre parênteses. Essa convençãode utilizar o mesmo mnemônico para duas instruções distintas é apenas uma conve-niência para o programador; é importante notar no entanto que para o processadoro que existe são duas instruções distintas, com codificações diferentes.
Exemplo 5
3.1. TRANSFERÊNCIA DE DADOS 15
LD
Carrega registrador com endereçamento indireto por registrador
Sintaxe Operação Flags Codificação
ld rdest, (rfonte) rdest ← mem[rfonte] –31 0
04 rdest rfonte
1 ; instrução carrega registrador com endereçamento2 ; indireto por registrador34 ld r6, (r5) ; código da instrução ocupa uma5 ; uma palavra: 04000605h
Antes
00 00 00 01 0300ch
03008h
03010h
00 00 30 0cr5
Memória
ff ff ff f0r6
00 00 01 acip
001ach
001b0h
04 00 06 05
Processador
Depois
00 00 00 01 0300ch
03008h
03010h
00 00 30 0cr5
Memória
00 00 00 01r6
00 00 01 b0ip
001ach
001b0h
04 00 06 05
Processador
16 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Carrega registrador com endereçamento indireto por registrador mais umaconstante
A instrução “carrega registrador com endereçamento indireto por registrador maisuma constante” é na verdade a mesma instrução que “carrega registrador com en-dereçamento indireto por registrador”. Apresentamos as duas instruções separa-damente apenas como forma mais didática de introduzir o modo de endereçamento“indireto por registrador mais constante”. Nesse novo modo de endereçamento o ope-rando fonte é uma expressão de adição, entre parênteses, em que um termo é o nomede um registrador e o outro termo é uma expressão constante com valor entre −128e 127. O termo constante é codificado no campo imd8; o endereço efetivo é calculadoefetuando a adição do valor do registrador com o valor de imd8 com o sinal esten-dido. O fato de que o bit de sinal de imd8 é estendido para compor o valor de 32 bitsé mostrado no campo Operação do descritor pela expressão ext(imd8).
LD
Carrega registrador com endereçamento indireto por registrador maisuma constante
Sintaxe Operação Flags Codificação
ld rdest, (rfonte + expr8)rdest ←
mem[rfonte + ext(imd8)]–
31 0
04 imd8 rdest rfonte
Exemplo 6
1 ; instrução carrega registrador com endereçamento2 ; indireto por registrador mais uma constante34 ld r2, (r3+8) ; código da instrução ocupa uma5 ; uma palavra: 04080605h6 ld r6, (r5-4) ; código da instrução ocupa uma7 ; uma palavra: 04fc02h
3.1. TRANSFERÊNCIA DE DADOS 17
Antes
00 00 40 04r5
Memória
55 55 55 55r6
00 00 02 00ip
99 99 99 99 04000h
03ffch
04004h
00200h
00204h
04 08 02 03
Processador
22 22 22 22r2
00 00 2f f8r3
77 77 77 77 03000h
02ffch
03004h
04 fc 06 05
Depois
00 00 40 04r5
Memória
99 99 99 99r6
00 00 02 08ip
99 99 99 99 04000h
03ffch
04004h
00200h
00204h
04 08 02 03
Processador
77 77 77 77r2
00 00 2f f8r3
77 77 77 77 03000h
02ffch
03004h
04 fc 06 05
É interessante notar que os modos de endereçamento “indireto por registrador”e “indireto por registrador mais uma constante” são implementados pela mesma ins-trução, com código 04h. Na verdade, a execução desta instrução do processadorsempre soma o valor do campo imd8 ao valor do registrador destino para encontraro valor do endereço efetivo do operando. Quando imd8 é zero resulta no modo deendereçamento “indireto por registrador”; quando imd8 é diferente de zero resultano modo de endereçamento “indireto por registrador mais uma constante”.
18 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Transferência de bytes entre a memória e um registrador
Como é muito comum a necessidade de manipular valores de 8 bits (especialmentecaracteres), o Faíska inclui também instruções para carregar um byte da memóriaem um registrador. Na instrução “Carrega registrador com byte da memória”, ape-nas um byte é carregado da memória para o registrador destino. O byte carregadoé colocado nos 8 bits menos significativos do registrador destino; os 24 bits maissignificativos do registrador são zerados.
O mnemônico utilizado pelo montador é ldb; como no caso da instrução ld, hádois modos de endereçamento possíveis: direto e indireto por registrador mais umaconstante.
LDB
Carrega registrador com byte da memória
Sintaxe Operação Flags Codificação
ldb rdest, expr32 rdest ← mem8[imd32] –
31 0
07 rdest
31 0
imd32
ldb rdest, (rfonte + expr8)rdest ←
mem8[rfonte + ext(imd8)]–
31 0
08 imd8 rdest rfonte
LDB
Carrega registrador com byte da memória
Sintaxe Operação Flags Codificação
ldb rdest, expr32 rdest ← mem8[imd32] –
31 0
07 rdest
31 0
imd32
ldb rdest, (rfonte + expr8)rdest ←
mem8[rfonte + ext(imd8)]–
31 0
08 imd8 rdest rfonte
Novamente, é interessante notar que os modos de endereçamento “indireto porregistrador” e “indireto por registrador mais uma constante” são implementados
3.1. TRANSFERÊNCIA DE DADOS 19
pela mesma instrução, com código 08h. Como comentado anteriormente„ a execuçãodesta instrução sempre soma o valor do campo imd8 ao valor do registrador destinopara encontrar o valor do endereço efetivo do operando, de fomra que o modo deendereçamento “indireto por registrador” pode ser entendido como um caso especialdo modo de endereçamento “indireto por registrador mais uma constante”, quando aconstante tem valor zero.
Exemplo 7
1 ; exemplo de instrução de carga de registrador com2 ; byte da memória3 ldb r13, carac+7 ; carrega byte cujo endereço4 ; é carac+75 ; código da instrução ocupa6 ; duas palavras:7 ; primeira palavra 07000d00h8 ; segunda palavra 0000400bh9 ldb r1, (r2) ; r2 tem endereço do byte que
10 ; queremos carregar em r1; código11 ; da instrução ocupa12 ; uma palavra: 08000102h13 ldb r12, (r2-1) ; r2-1 tem endereço do byte que14 ; queremos carregar em r12; código15 ; da instrução ocupa16 ; uma palavra: 08ff0c02h17 ...1819 org 4004h2021 carac: db ’U’, ’V’, ’W’, ’X’ ; uma variável qualquer que22 db ’a’, ’b’, ’c’, ’d’ ; representa uma sequência de23 ; bytes montada a partir do24 ; endereço 4008h
20 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Antes
64 63 62 61
55 56 57 58
04008h
04004h
0400ch
11 11 11 11r1
Memória
00 00 40 06r2
aa aa aa aar13
00 00 02 00ip
00204h
00200h07 00 0d 00
00 00 40 0b
08 00 01 02
Processador
00208h
0020ch
bb bb bb bbr12
00210h
08 00 01 02
Depois
64 63 62 61
55 56 57 58
04008h
04004h
0400ch
00 00 00 63r1
Memória
00 00 40 06r2
00 00 00 64r13
00 00 02 10ip
00204h
00200h07 00 0d 00
00 00 40 0b
08 00 01 02
Processador
00208h
0020ch
00 00 00 62r12
00210h
08 ff 0c 02
3.1.3 Transferência de um registrador para a memória
As instruções de transferência de um registrador para memória permitem armaze-nar o valor de um registrador em uma posição de memória, efetuando a operaçãoinversa das instruções de carga de registrador. No Faíska, estas instruções utilizamo mnemônico st (do inglês store, armazenar) e possui duas variantes, corresponden-tes aos modos de endereçamento direto e indireto por registrador.
3.1. TRANSFERÊNCIA DE DADOS 21
ST
Armazena de registrador na memória
Sintaxe Operação Flags Codificação
st (rdest + expr8), rfontemem[rdest+ext(imd8)] ←
rfonte–
31 0
05 rdest rfonte
st (rdest), expr32 mem[imd32]← rfonte –
31 0
06 rfonte
31 0
imd32
Armazena registrador em memória
Exemplo 8
1 ; exemplo de instrução armazena registrador na memória23 st var, r7 ; carrega byte cujo endereço4 ; é var5 ; código da instrução ocupa6 ; duas palavras:7 ; primeira palavra 05000007h8 ; segunda palavra 00001000h9 st (r4), r3 ; r5 tem endereço do byte que
10 ; queremos armazenar; código da11 ; instrução ocupa uma12 ; palavra: 06000403h1314 ...1516 org 1000h1718 var: ds 4 ; uma variável qualquer montada no19 ; endereço 1000h
22 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Antes
00 00 00 00
ff ff ff ff
01004h
01000h
01008h
ff ff ff ffr3
Memória
00 00 10 04r4
00 00 00 00r7
00 00 03 14ip
00314h
00318h
05 00 00 07
00 00 10 00
06 00 04 03
Processador
0031ch
00320h
Depois
ff ff ff ff
00 00 00 00
01004h
01000h
01008h
ff ff ff ffr3
Memória
00 00 10 04r4
00 00 00 00r7
00 00 03 20ip
00314h
00318h
05 00 00 07
00 00 10 00
06 00 04 03
Processador
0031ch
00320h
Armazena byte de registrador em memória
Exemplo 9
3.1. TRANSFERÊNCIA DE DADOS 23
STB
Armazena byte de registrador na memória
Sintaxe Operação Flags Codificação
stb (rdest), rfonte rdest ← mem8[rfonte] –31 0
0a rdest rfonte
stb (rdest), expr32 mem8[imd32]← rfonte –
31 0
0a rdest
31 0
imd32
1 stb carac+2, r4 ; carrega byte cujo endereço2 ; é carac+23 ; código da instrução ocupa4 ; duas palavras:5 ; primeira palavra 09000004h6 ; segunda palavra 00002002h7 stb (r5), r2 ; r5 tem endereço do byte que8 ; queremos armazenar; código9 ; da instrução ocupa uma
10 ; palavra: 0a000502h1112 ...1314 org 2000h1516 carac:17 ds 8 ; uma variável qualquer que18 ; representa uma sequência de19 ; 8 bytes montada a partir do20 ; endereço 2000h
24 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Antes
48 47 46 45
44 43 42 41
02004h
02000h
02008h
00 00 00 67r2
Memória
00 00 20 04r5
00 00 00 55r4
00 00 01 08ip
00108h
0010ch
09 00 00 04
00 00 20 02
0a 00 05 02
Processador
00110h
00114h
Depois
48 47 46 67
44 55 42 41
02004h
02000h
02008h
00 00 00 67r2
Memória
00 00 20 04r5
00 00 00 55r4
00 00 01 14ip
00108h
0010ch
09 00 00 04
00 00 20 02
0a 00 05 02
Processador
00110h
00114h
Podemos agora ver como traduzir, para linguagem de montagem, um pequenotrecho de programa escrito em linguagem C exemplificando o uso de variáveis e co-mandos de atribuição:
Exemplo 10 Traduzir o trecho abaixo, em linguagem C, contendo alguns comandos
de atribuição, para linguagem de montagem do Faíska.
3.2. INSTRUÇÕES ARITMÉTICAS 25
1 // Trecho de programa em C23 #define TAMANHO 25645 int a,b;6 char c;7 ...89 a = TAMANHO;
10 b = a;11 c = ’a’;
1 ; tradução para linguagem de montagem2 ; do trecho de programa acima34 TAMANHO equ 25656 ; reserva espaço para as variáveis7 org 20h8 a: ds 49 b: ds 4
10 c: ds 11112 org 100h13 set r0, TAMANHO ; r0 usado como auxiliar14 st a, r0 ; armazena valor na variável a15 st b, r0 ; armazena valor na variável b16 set r1, ’a’ ; r1 usado como auxiliar; note17 ; que r0 poderia ser reutilizado18 stb c, r1 ; armazena caractere na variável c19
3.2 Instruções aritméticas
No grupo das instruções aritméticas encontramos instruções para somar, subtrair,multiplicar e dividir números inteiros. Nesta seção estudaremos apenas as instru-ções para somar e subtrair; multiplicação e divisão serão apresentadas mais adiante.
No Faíska as instruções de soma e subtração têm sempre como operando des-tino um registrador; o segundo operando pode ser um outro registrador ou um valorimediato codificado em 8 bits (inteiro em complemento de dois).
26 CAPÍTULO 3. O PROCESSADOR FAÍSKA
ADD
Soma
Sintaxe Operação Flags Codificação
add rdest, expr8 rdest ← rdest + ext(imd8) CSZO31 0
10 imd8 rdest
add rdest, rfonte rdest ← rdest + rfonte CSZO31 0
11 rdest rfonte
3.2.1 Soma
Bits de estado
Note que na instrução add pela primeira vez o campo Flag do descritor de instruçãonão está vazio, e contém quatro letras. Essas letras representam bits de estado (eminglês, flags). No Faíska os bits de estado são:
• C: carry (vai-um). Ligado se operação causou vai-um (carry-out) ou vem-um(carry-in), desligado caso contrário.
• Z: zero. Ligado se o resultado foi zero, desligado caso contrário.
• S: sinal. Cópia do bit mais significativo do resultado; considerando aritméticacom sinal, se S igual a zero, o número é maior ou igual a zero. Se S igual a 1,resultado é negativo.
• O: overflow. Ligado se ocorreu estouro de campo; calculado como o ou-exclusivoentre o vem-um e o vai-um do bit mais significativo do resultado.
No descritor de instruções o campo Flag indica quais os bits de estado são afe-tados pela instrução; no caso da instrução add, todos os bits são afetados. Um bitde estado guarda a informação do resultado da última instrução executada que oafetou. Isto é, se uma instrução não afeta um determinado bit de estado, este per-manece com o mesmo valor anterior à execução da instrução. Bits de estado não sãoalterados por operações de transferência de dados.
Os bits de estado são armazenados em um registrador especial no Faíska, quenão é acessível através de instruções de carga. Nas figuras dos exemplos, esse regis-trador especial é mostrado com o nome flags. Veremos mais adiante como os bits deestado são utilizados para controlar o fluxo de execução de um programa.
3.2. INSTRUÇÕES ARITMÉTICAS 27
Exemplo 11 soma com endereçamento imediato e entre registradores.
1 add r4, 1 ; soma com valor imediato2 ; código da instrução ocupa3 ; uma palavra: 10010400h4 add r1, r2 ; soma dois registradores5 ; código da instrução ocupa6 ; uma palavra: 11000102h
00 03 00 00ip
Antes
80 00 11 11r1 Memória
80 00 00 abr2
00 ff ff ffr4 30000h
30004h
10 01 04 00
11 00 01 02
Processador
30008h
... 0 0 0 0flags
C S Z O
00 03 00 08ip
Depois
00 00 11 bcr1 Memória
80 00 00 abr2
01 00 00 00r4 30000h
30004h
10 01 04 00
11 00 01 02
Processador
30008h
... 1 0 0 1flags
C S Z O
3.2.2 Subtração
Exemplo 12 subtração com endereçamento imediato e entre registradores.
28 CAPÍTULO 3. O PROCESSADOR FAÍSKA
SUB
Subtração
Sintaxe Operação Flags Codificação
sub rdest, expr8 rdest ← rdest − ext(imd8) CSZO31 0
12 imd8 rdest
sub rdest, rfonte rdest ← rdest − rfonte CSZO31 0
13 rdest rfonte
1 sub r6, 1 ; soma com valor imediato2 ; código da instrução ocupa3 ; uma palavra: 12010600h4 sub r8, r7 ; soma registrador com registrador5 ; código da instrução ocupa6 ; uma palavra: 13000807h
00 05 00 00ip
Antes
10 00 00 00r6 Memória
ff ff ff ffr7
ff ff ff ffr8 50000h
50004h
12 01 06 00
13 00 08 07
Processador
50008h
... 0 0 0 0flags
C S Z O
3.2. INSTRUÇÕES ARITMÉTICAS 29
00 05 00 08ip
Depois
0f ff ff ffr6 Memória
ff ff ff ffr7
00 00 00 00r8 50000h
50004h
12 01 06 00
13 00 08 07
Processador
50008h
... 0 0 1 0flags
C S Z O
Exemplo 13 Considere o seguinte comando de atribuição em C:
1 var a, b, c: integer;23 ...45 a = b + c - 2;67 ...
Escreva um trecho de programa em linguagem de montagem que o implemente.
1 ; tradução para linguagem de montagem2 ; do trecho para implementar a = b + c - 234 ; reserva espaço para as variáveis inteiras a, b e c5 a: ds 46 b: ds 47 c: ds 48 ...9 ld r0, b ; r0 e r1 são usados como auxiliares
10 ld r1, c11 add r0, r1 ; r0 agora tem b+c12 sub r0, 213 st a, r0 ; e armazena o resultado
30 CAPÍTULO 3. O PROCESSADOR FAÍSKA
3.3 Instruções de desvio
Até agora, em todos os exemplos mostrados as instruções são executadas em seqüên-cia estrita das suas posições da memória, ou seja, o valor do registrador ip é sempreincrementado de quatro a cada instrução. Se não houver uma forma de fazer o valorde ip variar de maneira não seqüencial, fica impossível de implementar repetiçõescomo os comandos for e while em C ou Pascal. Para controlar o fluxo de execuçãodo programa, são usadas instruções de desvio, que alteram o valor do registradorinterno ip. Instruções de desvio podem ser condicionais ou incondicionais.
3.3.1 Desvio incondicional
A execução da instrução de desvio incondicional tem apenas um operando é bastantesimples: o valor do registrador ip é modificado para o valor do operando. Ou seja,o valor do operando é copiado para o registrador ip, fazendo com que a próximainstrução a ser executada tenha o endereço do operando, alterando dessa forma aexecução puramente sequencial de instuções vista até agora. Há duas instruções dedesvio incondicional: uma que é codificada em duas palavras, com a segunda palavracontendo o valor do endereço alvo do desvio, e uma instrução codificada em umapalavra, na qual o endereço alvo é dado em um registrador. O mnemônico utilizadopara as duas instruções é jmp, do inglês jump (salto).
JMP
Armazena byte de registrador na memória
Sintaxe Operação Flags Codificação
jmp expr32 ip ← imd32 –
31 0
2031 0
imd32
jmp rdest ip ← rdest –31 0
21 rdest
Exemplo 14 desvio incondicional
3.3. INSTRUÇÕES DE DESVIO 31
1 org 200h2 set r0, 0 ; uma instrução qualquer montada3 ; montada na posição 200h4 jmp fora ; instrução de desvio incondicional5 ; a codificação utiliza duas palavras:6 ; primeira palavra: 20000000h7 ; segunda palavra: 00003000h8 mov r1, r2 ; esta instrução não é executada9 ...
10 org 3000h11 fora:12 mov r2, r1 ; esta instrução é a próxima a ser13 ; executada após o desvio incondicional14
Antes
00 00 02 01
03004h
03000h
ff ff ff ffr0
Memória
11 11 11 11r1
22 22 22 22r2
00 00 02 00ip
00200h
00204h
01 00 00 00
20 00 00 00
00 00 30 00
00 00 01 02
Processador
00208h
0020ch
Depois
00 00 02 01
03004h
03000h
00 00 00 00r0
Memória
11 11 11 11r1
11 11 11 11r2
00 00 30 04ip
00200h
00204h
01 00 00 00
20 00 00 00
00 00 30 00
00 00 01 02
Processador
00208h
0020ch
Exemplo 15 desvio incondicional por registrador.
32 CAPÍTULO 3. O PROCESSADOR FAÍSKA
1 org 300h2 set r0, 1 ; uma instrução qualquer montada3 ; montada na posição 300h4 jmp r10 ; instrução de desvio incondicional5 ; a codificação utiliza uma palavra:6 ; 21000a00h7 mov r3, r4 ; esta instrução não é executada89 ...
1011 org 4000h12 fora:13 mov r4, r3 ; se r10 tem o valor 4000h, esta14 ; instrução é a próxima a ser executada15 ; após o desvio incondicional16
Antes
00 00 04 03
04004h
04000h
ff ff ff ffr0
Memória
33 33 33 33r3
44 44 44 44r4
00 00 40 00r10
00 00 02 00ip00300h
00304h
01 01 00 00
21 00 0a 00
00 00 03 04
Processador
00308h
0030ch
Depois
00 00 04 03
04004h
04000h
00 00 00 01r0
Memória
33 33 33 33r3
33 33 33 33r4
00 00 40 00r10
00 00 40 04ip00300h
00304h
01 01 00 00
21 00 0a 00
00 00 03 04
Processador
00308h
0030ch
3.3. INSTRUÇÕES DE DESVIO 33
3.3.2 Desvios condicionais
Instruções de desvio condicional são mais interessantes. Elas executam ou não odesvio dependendo do valor de um ou mais de bits de estado, que como já vimos sãoalterados pela execução de algumas instruções, em particular as instruções aritmé-ticas.
No Faíska, as operações de desvio condicional são codificadas em uma palavra.O cálculo do endereço alvo do desvio é diferente do caso do desvio incondicional, emque o endereço alvo é um valor absoluto, dado na segunda palavra da instrução.No caso das operações de desvio condicional, o processador utiliza o valor codificadono campo imd8 para calcular o endereço alvo. O endereço alvo é calculado de formarelativa ao valor corrente do registrador ip: o valor do campo imd8, transformado emum inteiro de 32 bits, com sinal, é adicionado ao valor corrente de ip para determinaro novo valor de ip.
Jcond
Desvio condicional
Sintaxe Operação Flags Codificação
jcond expr8 ip ← ip + ext(imd8) –31 0
xx imd8
No descritor, a sintaxe é dada como jcond expr8 pois no caso geral o operandoé uma expressão inteira cujo resultado deve ser possível armazenar em oito bits;mas na grande maioria dos casos a expressão é composta de apenas um rótulo. Omontador monta, no campo imd8, o valor da expressão (ip − endereço alvo). O valordo campo imd8 é interpretado como um inteiro com sinal, de forma que o endereçoalvo pode ser menor ou maior do que o ip corrente, fazendo com que o fluxo doprograma tenha um salto para trás (endereço alvo menor que o ip corrente) ou parafrente (endereço alvo maior que ip o corrente), respectivamente.
As instruções jl, jle, jg e jge (em inglês, respectivamente jump if less ejump less or equal, jump if greater e jump if greater or equal) devem ser usadasna comparação números inteiros com sinal; as instruções jc, jnc e ja (em inglês,respectivamente jump if carry, jump if not carry e jump if above) devem ser usadasna comparação de números inteiros sem sinal.
Exemplo 16
34 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Instr. Nome Cond. Codif.jc desvia se vai-um (menor sem sinal) C=1 22hjnc desvia se não vai-um (maior ou igual sem sinal) C=0 23hjz desvia se zero Z=1 24hjnz desvia se diferente de zero Z=0 25hjo desvia se overflow O=1 26hjno desvia se não overflow O=0 27hjs desvia se sinal igual a um S=1 28hjns desvia se sinal igual a zero S=0 29hjl desvia se menor (com sinal) S �=O 2ahjle desvia se menor ou igual (com sinal) Z=1 ou S �=O 2bhjg desvia se maior (com sinal) Z=0 e S=O 2chjge desvia se maior ou igual (com sinal) S=O 2eh
ja desvia se acima (maior sem sinal) C=0 e S=O 2fh
1 org 500h2 sub r8, 1 ; instrução montada na posição 300h3 jz final ; instrução de desvio condicional4 ; a codificação utiliza uma palavra:5 ; 24040000h6 set r8, 100 ; esta instrução é executada se o7 ; resultado da subtração for8 ; diferente de zero9 final:
10 mov r5, r6 ; esta instrução é a próxima a ser11 ; executada após o desvio condicional12 ; se o resultado da subtração for13 ; igual a zero14
Antes
55 55 55 55r5
Memória
66 66 66 66r6
00 00 00 01r8
00 00 05 00ip00500h
00504h
12 01 08 00
24 04 00 00
01 64 08 00
00 00 05 06
Processador
00508h
0050ch
00510h
3.3. INSTRUÇÕES DE DESVIO 35
Depois
66 66 66 66r5
Memória
66 66 66 66r6
00 00 00 00r8
00 00 05 10ip00500h
00504h
12 01 08 00
24 04 00 00
01 64 08 00
00 00 05 06
Processador
00508h
0050ch
00510h
Se um desvio condicional não puder ser montado porque o endereço alvo ficoumais distante que o permitido, é necessário inverter a condição usada e utilizar doisdesvios, um deles incondicional. Por exemplo, suponha que no trecho abaixo o ró-tulo muito_longe estiver muito distante do desvio condicional, de tal forma que adistância relativa não possa ser representada no campo imd8 da instrução jnc:
1 sub r2, r12 jnc muito_longe3 add r0, r34 ...5 muito_longe:6
O montador indicará um erro, informando que não é possível montar o pro-grama. Podemos re-escrever o trecho invertendo a lógica do desvio condicional (dejnc para jc) e utilizando um desvio incondicional adicional, eliminando o problema:
1 sub r2, r12 jc bem_perto3 jmp muito_longe4 bem_perto:5 add r0, r36 ...7 muito_longe:8
Mas note que este é praticamente o único caso em que dois desvios precisamser escritos sequencialmente; normalmente isto não é necessário, e dois desvios emsequência podem indicar uma construção errada, que pode ser melhorada para uti-
36 CAPÍTULO 3. O PROCESSADOR FAÍSKA
lizar apenas um desvio.
Exemplo 17 Escreva um trecho de programa que, dados dois números inteiros sem
sinal em r1 e r2, coloque em r1 o menor valor e em r2 o maior valor.
1 ordena:2 mov r0, r1 ; vamos usar r0 como rascunho3 sub r0, r2 ; valor de r1 é maior que r2?4 jc final ; não é --- nada a fazer5 mov r0, r1 ; troca r1 com r26 mov r1, r2 ; usando r07 mov r2, r0 ; como temporário8 final:9 ...
Exemplo 18 Escreva um trecho de programa que coloque no registrador r0 o maior
valor entre r1, r2 e r3. Suponha que os registradores contenham números inteiros
com sinal.
1 maior:2 mov r4, r1 ; usando r4 como rascunho3 sub r4, r2 ; compara r1 e r24 jge um ; desvia se r1 maior5 mov r4, r2 ; guarda maior valor em r46 mov r0, r2 ; e em r07 jmp outro8 um:9 mov r4, r1 ; guarda maior valor em r4
10 mov r0, r1 ; e em r011 outro:12 sub r4, r3 ; compara maior entre r1 e r2 com r313 jge final ; r3 é menor, r0 já tem maior valor14 mov r0, r3 ; maior e r315 final:16 ...
3.3.3 Nova instrução aritmética: comparação
O exemplo acima, que deveria ser bem simples, ficou um pouco mais extenso e com-plicado porque a instrução de subtração usada para comparar os registradores alterao valor do registrador destino. Isto faz com que precisemos usar registradores auxi-liares que devem ser reinicializados após cada subtração. Como comparação é umaoperação relativamente freqüente, ela é definida como uma instrução primitiva namaioria dos processadores. Esta nova instrução é bastante semelhante à instruçãosub, com a diferença de que o registrador destino não é alterado. Quer dizer, a sub-tração é efetuada, os bits de estado são modificados correspondentemente, mas oresultado não é colocado no registrador destino, que permanece com o valor inicial.
3.3. INSTRUÇÕES DE DESVIO 37
CMP
Comparação
Sintaxe Operação Flags Codificação
cmp rdest, expr8 rdest − ext(imd8) CSZO31 0
14 imd8 rdest
cmp rdest, rfonte rdest − rfonte CSZO31 0
15 rdest rfonte
Vamos re-escrever a solução para o Exemplo 18 com a instrução cmp.
1 maior:2 mov r0, r1 ; assume que r1 e o maior3 cmp r0, r2 ; compara r1 e r24 jge outro ; desvia se r1 maior5 mov r0, r2 ; r2 é maior, guarda em r06 outro:7 cmp r0, r3 ; compara maior entre r1 e r2 com r38 jge final ; r0 já tem o maior valor9 mov r0, r3 ; maior é r3
10 final:11 ... ; final do trecho
Exemplo 19 Escreva um trecho de programa que determine qual o maior valor de
uma cadeia de números de 32 bits, sem sinal, cujo endereço inicial é dado em r2.
Inicialmente, r3 contém o número de valores presentes na cadeia; suponha que r3 >
0. Ao final do trecho, r0 deve conter o valor máximo e r1 deve conter o endereço do
valor máximo.
38 CAPÍTULO 3. O PROCESSADOR FAÍSKA
1 inicio:2 mov r1, r2 ; guarda apontador para início3 mov r0, (r1) ; e valor máximo corrente4 proximo:5 add r2, 4 ; avança ponteiro para próximo elemento6 sub r3, 1 ; um elemento a mais verificado7 jz final ; terminou de verificar toda a cadeia?8 ld r4, (r2) ; não, então toma mais um valor9 cmp r0, r4 ; compara com máximo corrente
10 jnc proximo ; desvia se menor ou igual11 mov r2, r1 ; achamos um maior, guarda novo apontator12 mov r0, r4 ; e novo máximo13 jmp proximo ; e continua a percorrer a cadeia14 final:15 ... ; final do trecho
Note que o registrador que percorre a cadeia, r2, é incrementado de quatro acada elemento verificado, pois cada elemento ocupa quatro bytes.
Exemplo 20 Escreva um trecho de programa para mover um bloco de palavras de
memória da posição apontada por r1 para a posição apontada por r2. O tamanho
do bloco (número de palavras) que deve ser movido é dado em r3.
1 ; primeira versão...2 ; move bloco de palavras3 ; entrada:4 ; r1: endereço inicial do bloco5 ; r2: endereço para onde o bloco deve ser movido6 ; r3: tamanho do bloco, em palavras de 32 bits7 MoveBloco:8 ld r0, (r1) ; copia palavra9 st (r2), r0 ; na nova posição
10 add r1, 4 ; avança ponteiros11 add r2, 412 sub r3, 1 ; verifica se chegou ao final do bloco13 jnz MoveBloco ; não, continua movendo14 ... ; aqui quando terminou de mover o bloco
Infelizmente esta solução simples não funciona para todos os casos. A Figura3.2 ilustra de forma esquemática as configurações possíveis para este problema, de-pendendo do tamanho do bloco e de suas posições inicial e final. Na figura, os ende-reços da memória crescem da esquerda para a direita.
A solução apresentada funciona perfeitamente para os casos (a) e (b) da Figura3.2, quando não há interseção entre a posição original e a posição final do bloco, efunciona também para o caso (d).
3.3. INSTRUÇÕES DE DESVIO 39
r2(destino)
r1(origem)
(a)
r1(origem)
r2(destino)
(b)
r2(destino)
r1(origem)
(c)
r1(origem)
r2(destino)
(d)
Figura 3.2: Configurações possíveis no movimento de um bloco de memória da posi-ção apontada por r1 para a posição apontada por r2.
Mas no caso (c) a cópia das primeiras palavras destrói o conteúdo do bloco ori-ginal. Neste caso, é necessário fazer a cópia do final do bloco para o começo, comoesquematizado na Figura 3.3.
40 CAPÍTULO 3. O PROCESSADOR FAÍSKA
r2(final do destino)
r1(final da origem)
Figura 3.3: Deslocando os apontadores para o final das posições original e destinodos blocos.
1 ; versão final...2 ; move bloco de palavras3 ; entrada:4 ; r1: endereço inicial do bloco5 ; r2: endereço para onde o bloco deve ser movido6 ; r3: tamanho do bloco, em palavras de 32 bits7 MoveBloco:8 set r5, 4 ; vamos usar r5 para avançar os ponteiros9 cmp r1, r2 ; inicialmente verifica qual caso
10 jz inal ; origem = destino? nada a fazer11 ja vBloco ; casos (b) e (d), origem é menor...12 ; que destino, move do inicio para o fim1314 ; aqui tratamos casos (a) e (c) -- embora apenas (c) cause15 ; problema é mais fácil tratá-los juntos; move do fim para16 ; o início17 set r5, -4 ; o ‘avanço’ vai ser para trás18 mov r0, r3 ; r0 é rascunho, vamos calcular o endereço19 ; da última palavra de cada bloco20 add r0, r0 ; r0 = 2*tamanho21 add r0, r0 ; r0 = 4*tamanho, ou seja, número de bytes22 sub r0, 423 add r1, r0 ; r1 aponta para última palavra da origem24 add r2, r0 ; r2 aponta para última palavra da destino25 MvBloco:26 ld r0, (r1) ; copia palavra27 st (r2), r0 ; na nova posição28 add r1, r5 ; avança (ou retrocede) ponteiros29 add r2, r530 sub r3, 1 ; verifica se chegou ao final do bloco31 jnz MvBloco ; não, continua movendo32 final:33 ... ; aqui quando terminou de mover o bloco
Exemplo 21 Escreva um trecho de programa que verifique se uma cadeia de bytes é
palíndrome (ou seja, dá o mesmo resultado quando lida da direita para a esquerda
3.3. INSTRUÇÕES DE DESVIO 41
ou da esquerda para a direita; “roma amor” é um exemplo). O endereço do início da
cadeia é dado em r2, e o seu comprimento (maior ou igual a 0) é dado em r1. Se a
cadeia é palíndrome, o registrador r0 deve valer zero ao final; caso contrário, r0 deve
ter o valor 1 ao final.
1 ;trecho para verificar se cadeia de bytes é palíndrome2 ; no início: endereço inicial da cadeia em r2 e3 ; seu comprimento em r14 ; no final: r0 igual a 0 se palíndrome, 1 caso contrário56 Palíndrome:7 cmp r1, 0 ; se cadeia vazia, palavra é palíndrome8 jz palind ; vai retornar com r0 igual a 09 mov r3, r2 ; vamos fazer ...
10 add r3, r1 ; r3 apontar ...11 sub r3, 1 ; para último elemento da cadeia12 proxbyte:13 ldb r0, (r2) ; elemento do início14 ldb r1, (r3) ; elemento do final15 cmp r0, r1 ; campara os elementos16 jnz naopal ; se diferentes, palavra não é palíndrome17 add r2, 1 ; avança ponteiro do inicio18 sub r3, 1 ; retrocede ponteiro do final19 cmp r2, r3 ; verifica se cadeia terminou20 jnc palind ; sim, terminou, a palavra é palíndrome21 jmp proxbyte ; continua verificação22 naopal:23 set r0, 124 jmp final ; termina com r0 igual a 125 palind:26 set r0, 0 ; termina com r0 igual a 027 final:
Essa solução pode ser melhorada. Primeiramente, note que existe uma seqüên-cia de dois desvios, o primeiro condicional e o segundo incondicional, nas linhas li-nhas 19∼22. Quando isto ocorre, podemos em geral rearrumar o código de maneiraa utilizar apenas um desvio. Uma outra modificação possível é a eliminação do testepara verificar se a cadeia é vazia no início (linhas 6∼9), incorporando este caso notratamento geral. A nova versão fica assim:
42 CAPÍTULO 3. O PROCESSADOR FAÍSKA
1 ; Palíndrome - segunda versão2 ;trecho para verificar se cadeia de bytes é palíndrome3 ; no início: endereço inicial da cadeia em r2 e seu4 ; comprimento em r15 ; no final: r0 igual a 0 se palíndrome, 1 caso contrário6 ; destrói: r1, r2 e r37 Palíndrome:8 cmp r1, 0 ; se cadeia vazia, palavra é palíndrome9 jz palind ; vai retornar com r0 igual a 0
10 mov r3, r2 ; vamos fazer ...11 add r3, r1 ; r3 apontar ...12 sub r3, 1 ; para último elemento da cadeia13 proxbyte:14 cmp r2, r3 ; verifica se cadeia terminou15 jnc palind ; sim, terminou, a palavra é palíndrome16 ldb r0, (r2) ; elemento do inicio17 ldb r1, (r3) ; elemento do final18 add r2, 1 ; avança ponteiro do inicio19 sub r3, 1 ; retrocede ponteiro do final20 cmp r0, r1 ; campara os elementos21 jz proxbyte22 set r0, 123 jmp final ; termina com r0 igual a 124 palind:25 set r0, 0 ; termina com r0 igual a 026 final:
Tabelas de desvios
Uma técnica bastante útil em linguagem de montagem é a utilização de tabelas dedesvio. Para ilustrar o seu uso, vamos examinar como pode ser implementado umcomando de seleção como switch em C.
Considere o seguinte trecho de programa em C:
1 switch(val) {2 case 1000:3 x= y; break;4 case 1001:5 y = x; break;6 case 1004:7 t = x;8 case 1005:9 x = 0; break;
10 default:11 x = y = t = 0;12 }
3.3. INSTRUÇÕES DE DESVIO 43
Uma maneira de implementar este trecho em linguagem de montagem é com-parar o valor de val sequencialmente com cada um das possíveis seleções, como notrecho em linguagem de montagem abaixo:
1 ; comando switch (val)2 ld r0, val ; carrega variavel de seleção3 set r1, 1000 ; primeira selação4 cmp r0, r1 ; verifica se igual5 jnz sel2 ; desvia se diferente6 ; case 10007 ld r0, y8 st x, r0 ; x = y9 jmp final ; break
10 sel2:11 set r1, 1001 ; segunda selação12 cmp r0, r1 ; verifica se igual13 jnz sel3 ; desvia se diferente14 ; case 100115 ld r0, x16 st y, r0 ; y = x17 jmp final ; break18 sel3:19 set r1, 1004 ; terceira selação20 cmp r0, r1 ; verifica se igual21 jnz sel4 ; desvia se diferente22 ; case 100423 ld r0, x24 st t, r0 ; t = x25 jmp s1005 ; note que não há break26 sel4:27 set r1, 1005 ; quarta selação28 cmp r0, r1 ; verifica se igual29 jnz sel5 ; desvia se diferente30 ; case 100531 s1005:32 set r0, 033 st t, r0 ; t = 034 jmp final ; break35 ; default36 sel5:37 set r0, 038 st t, r0 ; t = 039 st x, r0 ; x = 040 st y, r0 ; y = 041 final:42 ...
Esta solução é aplicável quando o número N de seleções é pequeno. Mas noteque a cada execução do comando switch são realizadas em média N/2 comparações.Se N é grande, a execução do comando será (em média) demorada. Nesse caso o
44 CAPÍTULO 3. O PROCESSADOR FAÍSKA
mais eficiente é usar uma tabela de desvios, que é simplesmente uma tabela ondecada elemento é um rótulo:
1 tabela_desvio:2 dw ponto13 dw ponto24 dw ponto35 ...6 dw pontoN7
Para efetuar o desvio para a posição referente ao segundo elemento da tabela,basta carregar este elemento em um registrador e utilizar a instrução de desvio porregistrador.
Um exemplo de implementação do comandoswitch acima utilizando uma tabelade desvio é:
3.3. INSTRUÇÕES DE DESVIO 45
1 ; comando switch (val)2 ld r0, val ; carrega variavel de seleção3 set r1, 1000 ; primeiro verificamos os limites4 cmp r0, r1 ; menor que menor entrada na tabela?5 jc casedefault ; sim, desvia6 set r1, 1005 ; compara com maior valor7 cmp r1, r08 jc casedefault ; val é maior que a maior entrada na tabela9 set r1, tab_switch ; carrega endereço da tabela de desvios
10 ; r0 será o índice na tabela11 sub r0, 1000 ; primeiro valor tem índice zero12 add r0, r0 ; cada elemento na tabela tem 4 bytes...13 add r0, r0 ; portanto multiplicamos índice por 414 add r0, r1 ; r0 aponta para elemento15 ld r0, (r0) ; pega elemento na tabela16 jmp r0 ; e desvia para seleção correspondente17 tab_switch:18 dw case100019 dw case100120 dw casedefault21 dw casedefault22 dw case100423 dw case100524 case1000:25 ld r0, y26 st x, r0 ; x = y27 jmp final ; break28 case1001:29 ld r0, x30 st y, r0 ; y = x31 jmp final ; break32 case1004:33 ld r0, x34 st t, r0 ; t = x35 ; note que não há break36 case1005:37 set r0, 038 st t, r0 ; t = 039 jmp final ; break40 casedefault:41 set r0, 042 st t, r0 ; t = 043 st x, r0 ; x = 044 st y, r0 ; y = 045 final:46 ...
Nesta implementação o número de comparações a cada execução do comandoswitch é fixo, independente do número de opções existentes.
46 CAPÍTULO 3. O PROCESSADOR FAÍSKA
3.4 Instruções Lógicas
No grupo das instruções lógicas, como o nome indica, estão as instruções que efe-tuam operações lógicas como e, ou e ou-exclusivo. No Faíska, as instruções lógicasoperam somente sobre registradores; ou seja, os dois operandos das instruções sãoregistradores. Outros processadores, como os da família Intel x86, admitem que umdos operandos esteja na memória.
As operações lógicas para operandos de apenas um bit são descritas na Figura3.4. As instruções lógicas que implementam as operações E, OU e OU-EXCLUSIVOoperam bit a bit, isto é, bit 0 do primeiro operando com bit 0 do segundo operando,bit 1 com bit 1, e assim por diante.
op1 op2 E0 0 00 1 01 0 01 1 1
op1 op2 OU0 0 00 1 11 0 11 1 1
op1 op2 OU-EXCLUSIVO0 0 00 1 11 0 11 1 0
Figura 3.4: Operações lógicas com operandos de 1 bit
AND
E-Lógico
Sintaxe Operação Flags Codificação
and rdest, rfonte rdest ← rdest ∧ rfonte SZ31 0
30 rdest rfonte
Exemplo 22
1 org 100h2 and r2, r3 ; instrução e-lógico3 ; a codificação utiliza uma palavra:4 ; 300002035
3.4. INSTRUÇÕES LÓGICAS 47
Antes
30 00 02 03 00100h
000fch
00104h
88 00 e8 f2r2Memória
f7 ea 12 66r3
00 00 01 00ip
Processador
... 0 0 flags
S Z
00 00 01 04ip
Depois
30 00 02 03 00100h
000fch
00104h
80 00 00 62r2Memória
f7 ea 12 66r3
Processador
... 1 0 flags
S Z
OR
OU-Lógico
Sintaxe Operação Flags Codificação
or rdest, rfonte rdest ← rdest ∨ rfonte SZ31 0
31 rdest rfonte
Exemplo 23
1 org 100h2 or r2, r3 ; instrução ou-lógico3 ; a codificação utiliza uma palavra:4 ; 310002035
48 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Antes
31 00 02 03 00100h
000fch
00104h
88 00 e8 f2r2Memória
f7 ea 12 66r3
00 00 01 00ip
Processador
... 0 0 flags
S Z
Depois
31 00 02 03 00100h
000fch
00104h
ff ea fa f6r2Memória
f7 ea 12 66r3
00 00 01 04ip
Processador
... 0 1 0 0flags
C S Z O
XOR
OU-Exclusivo
Sintaxe Operação Flags Codificação
xor rdest, rfonte rdest ← rdest ⊕ rfonte SZ31 0
32 rdest rfonte
Exemplo 24
1 org 100h2 xor r2, r3 ; instrução ou-exclusivo3 ; a codificação utiliza uma palavra:4 ; 320002035
3.4. INSTRUÇÕES LÓGICAS 49
Antes
32 00 02 03 00100h
000fch
00104h
88 00 e8 f2r2Memória
f7 ea 12 66r3
00 00 01 00ip
Processador
... 0 0 flags
S Z
Depois
32 00 02 03 00100h
000fch
00104h
7f ea fa 94r2Memória
f7 ea 12 66r3
00 00 01 04ip
Processador
... 0 0flags
S Z
TEST
OU-Exclusivo
Sintaxe Operação Flags Codificação
test rdest, rfonte rdest ∧ rfonte SZ31 0
33 rdest rfonte
Exemplo 25
1 org 100h2 test r2, r3 ; instrução test3 ; como and, mas não armazena resultado4 ; a codificação utiliza uma palavra:5 ; 330002036
50 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Antes
33 00 02 03 00100h
000fch
00104h
88 00 e8 f2r2Memória
f7 ea 12 66r3
00 00 01 00ip
Processador
... 0 0 flags
S Z
00 00 01 04ip
Depois
30 00 02 03 00100h
000fch
00104h
88 00 e8 f2r2Memória
f7 ea 12 66r3
Processador
... 1 0 flags
S Z
As instruções lógicas podem ser utilizadas por exemplo para implementar va-riáveis do tipo conjunto. Por exemplo, para implementar um conjunto que tenha nomáximo 32 elementos podemos utilizar uma palavra de memória, na qual cada bitcorresponde a um elemento do conjunto. Usando as instruções lógicas e máscarasde bits apropriadas podemos inserir um elemento, remover um elemento ou testar apresença de um elemento no conjunto.
Exemplo 26
3.4. INSTRUÇÕES LÓGICAS 51
1 ; algumas máscaras de bits, uma para cada cor; em cada máscara2 ; há apenas um bit um, na posição correspondente à cor3 azul equ 01h4 verde equ 02h5 roxo equ 04h6 ...7 preto equ 40000000h8 branco equ 80000000h9 ...
1011 org 1000h12 ; reserva espaço para a variável que representa o conjunto13 cores: ds 414 ...1516 org 2000h17 ; insere o elemento azul no conjunto18 ld r1, cores19 set r0, azul ; máscara para elemento a inserir20 or r1, r021 st cores, r1 ; conjunto agora contém azul2223 ...2425 ; remove o elemento verde do conjunto26 ld r1, cores27 set r0, verde ; máscara para elemento a remover28 set r2, -1 ; máscara para inverter com xor29 xor r0, r2 ; máscara agora é 0fffffffdh30 and r1, r0 ; zera bit correspondente a verde31 ; mantém todos os outros32 st cores, r1 ; conjunto agora não contém verde3334 ...3536 ; testa presença do elemento roxo no conjunto37 ld r1, cores38 set r0, roxo ; máscara para elemento39 test r1, r0 ; verifica bit correspondente a roxo40 jnz presente41 ; aqui quando conjunto não contém roxo42 ...43 presente:44 ; aqui quando conjunto contém roxo
No Exemplo 26 a variável é carregada para um registrador a cada início de ope-ração sobre o conjunto, e o registrador é armazenado de volta na variável a cada finalde operação porque são descritos apenas trechos de código, e estamos assumindo queentre os trechos mostrados o registrador r1 é utilizado para outros fins. Se o regis-trador não for utilizado para outros fins, obviamente as instruções intermediárias decarga e armazenamento podem ser eliminadas.
52 CAPÍTULO 3. O PROCESSADOR FAÍSKA
A instrução and pode também ser usada para isolar alguns bits de uma palavrade memória. Suponha que uma palavra de 32 bits está sendo usada para armazenarquatro elementos de uma estrutura, onde cada elemento é um número de oito bits,como na declaração em C abaixo:
struct exemplo {char x,y,t,z;
} exemplo;z xyt
31 081624
Para isolar apenas o elemento x, podemos utilizar o seguinte trecho de código:
1 ; reserva espaço para a estrutura2 exemplo:3 ds 44 ...5 ; aqui inicia o trecho para isolar o elemento x6 ld r10, exemplo ; carrega estrutura7 set r0, 0ffh ; máscara 00 00 00 ff8 and r10, r0 ; r10 tem o elemento x isolado
Para isolar y, o segundo elemento da estrutura, podemos nos valer da mesmaideia, e utilizar uma máscara com valor 0ff00h:
1 ; aqui inicia o trecho para isolar o elemento y2 ld r9, exemplo ; carrega estrutura3 set r0, 0ff00h ; máscara 00 00 ff 004 and r9, r0 ; r9 tem o elemento y isolado
No entanto, apesar de o elemento y estar isolado ao final do trecho, ele não estáposicionado no byte menos significativo de r9. Assim, fica impossível por exemplocomparar se x e y têm o mesmo valor. Para tanto, seria necessário deslocar o valorde r9 de oito bits para a direita.
Os processadores incluem no repertório instruções que permitem diferentes for-mas de efetuar deslocamentos deste tipo: para a direita, para a esquerda, e aindaoutras formas. Estas instruções são apresentadas na seção a seguir.
3.5. INSTRUÇÕES DE DESLOCAMENTO 53
3.5 Instruções de deslocamento
As instruções de deslocamento do Faíska operam sempre sobre um registrador, edeslocam os bits do registrador operando para a direita ou para a esquerda. Todosos bits são deslocados ao mesmo tempo. Por exemplo, no deslocamento simples paraa esquerda, o bit b0 (menos significativo) do registrador é deslocado para a posiçãodo bit b1, que por sua vez é deslocado para a posição do bit b2, e assim por diante. AFigura 3.5 ilustra as operações de deslocamento para a esquerda e para a direita.
x b31 b1b2b3b30...
(b)
b31 b30 b0b1b2b29...
Antes
Depois
sentido do deslocamento
b0
x
b29 xb0b1b28...
(a)
b31 b30 b0b1b2b29...
Antes
Depois
sentido do deslocamento
b31
x
b30
Figura 3.5: Operações de deslocamento (a) para a esquerda e (b) para a direita
As variações existentes das instruções de deslocamento derivam das diferentespossibilidades sobre o que acontece com o bit que ‘sai’ do registrador (b0 no deslo-camento para a direita e b31 no deslocamento para a esquerda) e sobre o bit que‘entra’ no registrador (representado por x na Figura 3.5, que ‘entra’ no lugar de b31
no deslocamento para a direita e no lugar de b0 no deslocamento para a esquerda).Em todas as instruções de deslocamento o número de bits que o registrador deve
ser deslocado é dado no segundo operando, que pode ser uma constante codificadacom endereçamento imediato, ou pode ser um outro registrador. Quando a instruçãoindica que o registrador deve ser deslocado de mais do que um bit (ou seja, o valordo segundo operando é maior do que um) a operação de deslocamento ilustrada naFigura 3.5 é repetida o número de vezes indicado pelo valor do segundo operando.
3.5.1 Deslocamento simples
Nas instruções de deslocamento simples o bit que é ‘ejetado’ do registrador é copiadono bit de estado C. Se a instrução de deslocamento indica que o registrador deve serdeslocado de mais de um bit, o valor copiado no bit de estado é o último a ser ‘ejetado’do registrador. O valor do bit que ‘é injetado’ a cada deslocamento é sempre igual azero.
54 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Deslocamento para a direita
SHR
Deslocamento para a direita
Sintaxe Operação Flags Codificação
shr rdest, expr5
repita imd5 vezes {rdest[i]← rdest[i + i]C ← rdest[0]rdest[31]← 0
}
CSZ31 0
40 imd8 rdest
shr rdest, rfonte
repita rfonte vezes {rdest[i]← rdest[i + i]C ← rdest[0]rdest[31]← 0
}
CSZ31 0
41 rdest rfonte
Exemplo 27
1 org 200h2 shr r10, 1 ; deslocamento para a direita, imediato3 ; a codificação utiliza uma palavra:4 ; 40010a005 shr r11, r3 ; deslocamento para a direita6 ; a codificação utiliza uma palavra:7 ; 41000b038
Antes
00 00 00 07r3
Memória
55 55 55 55r10
ff 00 00 00r11
00 00 02 00ip
00200h
00204h
40 01 0a 00
41 00 0b 03
Processador
00208h
... 0 0 0 flags
C S Z
3.5. INSTRUÇÕES DE DESLOCAMENTO 55
Depois
00 00 00 07r3
Memória
2a aa aa aar10
01 fe 00 00r11
00 00 02 08ip
00200h
00204h
40 01 0a 00
41 00 0b 03
Processador
00208h
... 0 0 0 flags
C S Z
Deslocamento para a esquerda
SHL
Deslocamento para a esquerda
Sintaxe Operação Flags Codificação
shl rdest, expr5
repita imd5 vezes {rdest[i + 1]← rdest[i]C ← rdest[31]rdest[0]← 0
}
CSZ31 0
42 imd8 rdest
shl rdest, rfonte
repita rfonte vezes {rdest[i + 1]← rdest[i]C ← rdest[31]rdest[0]← 0
}
CSZ31 0
43 rdest rfonte
Exemplo 28
1 org 200h2 shl r10, 1 ; deslocamento para a esquerda, imediato3 ; a codificação utiliza uma palavra:4 ; 42010a00h5 shl r11, r3 ; deslocamento para a esquerda6 ; a codificação utiliza uma palavra:7 ; 43000b03h8
56 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Antes
00 00 00 07r3
Memória
55 55 55 55r10
ff 00 00 00r11
00 00 02 00ip
00200h
00204h
42 01 0a 00
43 00 0b 03
Processador
00208h
... 0 0 0 flags
C S Z
Depois
00 00 00 07r3
Memória
aa aa aa aar10
80 00 00 00r11
00 00 02 08ip
00200h
00204h
42 01 0a 00
43 00 0b 03
Processador
00208h
... 1 1 0 flags
C S Z
Deslocamento aritmético para a direita
Operações de deslocamento são muito úteis para efetuar a divisão ou multiplicaçãode um número inteiro por uma potência de 2. Como visto no Capítulo ??, cada des-locamento de um bit para a direita divide o operando por dois, e cada deslocamentode um bit para a esquerda multiplica o operando por 2, se o operando é um númerointeiro positivo. Se o operando é um número inteiro negativo, a instrução de desloca-mento simples para a direita não pode ser usada para dividí-lo por 2, pois como zerossão injetados o resultado será sempre positivo. Por esta razão uma outra instruçãode deslocamento é fornecida pelo Faíska, o deslocamento aritmético para a direita.
A diferença entre o deslocamento simples e o aritmético é que no aritmético aoinvés de serem injetados zeros, o bit mais significativo do operando é usado na inje-ção. Ou seja, o bit de sinal do operando é repetido e deslocado para a direita. Assim,quando o operando representar um número inteiro com sinal em complemento dedois, se o valor inicial é negativo, o resultado também o será (e valerá metade dovalor inicial). Observe que a instrução simétrica sal não é necessária.
3.5. INSTRUÇÕES DE DESLOCAMENTO 57
SAR
Deslocamento aritmético para a direita
Sintaxe Operação Flags Codificação
sar rdest, expr5
repita imd5 vezes {rdest[i]← rdest[i + i]C ← rdest[0]rdest[31]← 0
}
CSZ31 0
44 imd5 rdest
sar rdest, rfonte
repita rfonte vezes {rdest[i]← rdest[i + i]C ← rdest[0]rdest[31]← rdest[31]
}
CSZ31 0
45 rdest rfonte
Exemplo 29
1 org 200h2 sar r10, 1 ; deslocamento aritmético, imediato3 ; a codificação utiliza uma palavra:4 ; 44010a00h5 sar r11, r3 ; deslocamento aritmético, com registrador6 ; a codificação utiliza uma palavra:7 ; 45000b03h8
Antes
00 00 00 07r3
Memória
55 55 55 55r10
ff 00 00 00r11
00 00 02 00ip
00200h
00204h
44 01 0a 00
45 00 0b 03
Processador
00208h
... 0 0 0 flags
C S Z
58 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Depois
00 00 00 07r3
Memória
2a aa aa aar10
ff fe 00 00r11
00 00 02 08ip
00200h
00204h
44 01 0a 00
45 00 0b 03
Processador
00208h
... 0 1 0 flags
C S Z
3.5.2 Deslocamentos com rotação
No deslocamento com rotação, o bit ejetado do registrador é injetado novamente,ou diretamente no registrador, no lado oposto de onde o bit foi ejetado (no caso dasinstruções de rotação para a direita e para a esquerda), ou no bit de estado vai-um (bit C), no caso das instruções de rotação com vai-um para a esquerda e para adireita.
Rotação para a direita
ROR
Deslocamento aritmético para a direita
Sintaxe Operação Flags Codificação
ror rdest, expr5
repita imd5 vezes {rdest[i]← rdest[i + 1]C ← rdest[0]rdest[31]← rdest[0]
}
CSZ31 0
48 imd5 rdest
ror rdest, rfonte
repita rfonte vezes {rdest[i]← rdest[i + 1]C ← rdest[0]rdest[31]← rdest[0]
}
CSZ31 0
49 rdest rfonte
Exemplo 30
3.5. INSTRUÇÕES DE DESLOCAMENTO 59
1 org 200h2 ror r10, 1 ; rotação para a direita, imediato3 ; a codificação utiliza uma palavra:4 ; 48010a00h5 ror r11, r3 ; rotação para a direita, com registrador6 ; a codificação utiliza uma palavra:7 ; 49000b03h8
Antes
00 00 00 07r3
Memória
55 55 55 55r10
ff 00 00 00r11
00 00 02 00ip
00200h
00204h
48 01 0a 00
49 00 0b 03
Processador
00208h
... 0 0 0 flags
C S Z
Depois
00 00 00 07r3
Memória
55 55 55 55r10
1f e0 00 00r11
00 00 02 08ip
00200h
00204h
48 01 0a 00
49 00 0b 03
Processador
00208h
... 0 0 0 flags
C S Z
Rotação para a esquerda
Exemplo 31
60 CAPÍTULO 3. O PROCESSADOR FAÍSKA
ROL
Deslocamento aritmético para a direita
Sintaxe Operação Flags Codificação
rol rdest, expr5
repita imd5 vezes {rdest[i + 1]← rdest[i]C ← rdest[31]rdest[0]← rdest[31]
}
CSZ31 0
46 imd5 rdest
rol rdest, rfonte
repita rfonte vezes {rdest[i + 1]← rdest[i]C ← rdest[31]rdest[0]← rdest[31]
}
CSZ31 0
47 rdest rfonte
1 org 200h2 rol r10, 1 ; rotação para a esquerda, imediato3 ; a codificação utiliza uma palavra:4 ; 46010a00h5 rol r11, r3 ; rotação para a esquerda, com registrador6 ; a codificação utiliza uma palavra:7 ; 47000b03h8
Antes
00 00 00 07r3
Memória
55 55 55 55r10
ff 00 00 00r11
00 00 02 00ip
00200h
00204h
46 01 0a 00
47 00 0b 03
Processador
00208h
... 1 0 0 flags
C S Z
3.5. INSTRUÇÕES DE DESLOCAMENTO 61
Depois
00 00 00 07r3
Memória
55 55 55 55r10
80 00 00 3fr11
00 00 02 08ip
00200h
00204h
46 01 0a 00
47 00 0b 03
Processador
00208h
... 1 1 0 flags
C S Z
Rotação com vai-um para a direita
RCR
Deslocamento aritmético para a direita
Sintaxe Operação Flags Codificação
rcr rdest, expr5
repita imd5 vezes {rdest[i]← rdest[i + 1]rdest[31]← CC ← rdest[0]
}
CSZ31 0
48 imd5 rdest
rcr rdest, rfonte
repita rfonte vezes {rdest[i]← rdest[i + 1]rdest[31]← CC ← rdest[0]
}
CSZ31 0
49 rdest rfonte
Exemplo 32
62 CAPÍTULO 3. O PROCESSADOR FAÍSKA
1 org 200h2 rcr r10, 1 ; rotação para a direita com vai-um,3 ; imediato4 ; a codificação utiliza uma palavra:5 ; 4c010a00h6 rcr r11, r3 ; rotação para a direita com vai-um,7 ; com registrador8 ; a codificação utiliza uma palavra:9 ; 4d000b03h
10
Antes
00 00 00 07r3
Memória
55 55 55 55r10
ff 00 00 00r11
00 00 02 00ip
00200h
00204h
4c 01 0a 00
4d 00 0b 03
Processador
00208h
... 1 0 0 flags
C S Z
Depois
00 00 00 07r3
Memória
aa aa aa aar10
3f e0 00 00r11
00 00 02 08ip
00200h
00204h
4c 01 0a 00
4d 00 0b 03
Processador
00208h
... 0 0 0 flags
C S Z
Rotação com vai-um para a esquerda
Exemplo 33
3.5. INSTRUÇÕES DE DESLOCAMENTO 63
RCL
Deslocamento aritmético para a direita
Sintaxe Operação Flags Codificação
rcl rdest, expr5
repita imd5 vezes {rdest[i + 1]← rdest[i]rdest[0]← CC ← rdest[31]
}
CSZ31 0
4b imd5 rdest
rcl rdest, rfonte
repita rfonte vezes {rdest[i + 1]← rdest[i]C ← rdest[31]rdest[0]← rdest[31]
}
CSZ31 0
4c rdest rfonte
1 org 200h2 rcl r10, 1 ; rotação com vai-um para a esquerda,3 ; imediato4 ; a codificação utiliza uma palavra:5 ; 4a010a00h6 rcl r11, r3 ; rotação com vai-um para a esquerda,7 ; com registrador8 ; a codificação utiliza uma palavra:9 ; 4b000b03h
10
Antes
00 00 00 07r3
Memória
55 55 55 55r10
ff 00 00 00r11
00 00 02 00ip
00200h
00204h
4a 01 0a 00
4b 00 0b 03
Processador
00208h
... 1 0 0 flags
C S Z
64 CAPÍTULO 3. O PROCESSADOR FAÍSKA
Depois
00 00 00 07r3
Memória
aa aa aa abr10
80 00 00 ffr11
00 00 02 08ip
00200h
00204h
4a 01 0a 00
4b 00 0b 03
Processador
00208h
... 1 1 0 flags
C S Z
A Figura 3.5.2 mostra um resumo das operações de deslocamento de formaesquemática.
031Creg
shldeslocamento para a esquerda
031Creg
shrdeslocamento para a direita
0 0
031Creg
sardeslocamento aritmético para a direita
031Creg
rolrotação para a esquerda
031Creg
rorrotação para a direita
031Creg
rolrotação com vai-umpara a esquerda
rcrrotação com vai-um para a direita
031Creg
Figura 3.6: Resumo das instruções de deslocamento e rotação
3.5. INSTRUÇÕES DE DESLOCAMENTO 65
xy
31
Antes
0
yx
31
Depois
0
Figura 3.7: Invertendo o bit mais significativo com o menos significativo.
Exemplo 34 Vamos escrever um trecho de programa que troque os bits mais e menos
significativos de r0, sem alterar os bits restantes, como ilustrado na Figura 3.7.
1 ; trecho para inverter o bit mais significativo com o menos2 ; significativo de r03 ; r0 tem ybb..bbx4 xor r1, r1 ; zera r1, vamos montar x00..00y em r15 shr r0, 1 ; C = x, r0 tem 0ybb..bb6 rcr r1, 2 ; r1 tem 0x00..007 shl r0, 2 ; C = y, r0 tem bb..bb008 rcl r1, 1 ; r1 tem x00...00y9 shr r0, 1 ; r0 tem 0bb...bb0
10 or r0, r1 ; e bits são invertidos!
Exemplo 35 Suponha que r12 contém o endereço inicial de uma cadeia de oito ca-
racteres ‘0’ ou ‘1’ que representa um número em notação binária. r12 aponta para
o caractere que representa o “bit mais significativo” da cadeia. Vamos escrever um
trecho de programa que coloque em r0 o valor que a cadeia dada representa. Por
exemplo, se a cadeia de caracteres é ‘01011011’ (em hexadecimal, os valores dos ca-
racteres são 30h, 31h, 30h, 31h, 31h, 30h, 31h, 31h), o valor de r0 ao final do trecho
deve ser 5bh.
1 ; trecho para calcular valor binário representado por uma2 ; cadeia de caracteres ’0’ e ’1’ apontada por r123 ; primeira versão45 set r1, 8 ; vamos usar como contador6 xor r0, r0 ; r0 será usado como temporário7 set r11, 1 ; auxiliar, mascara para bit 08 ; vamos montar valor bit a bit9 prox_dig:
10 ldb r2, (r12) ; r2 tem dígito: 30h ou 31h11 shl r0, 1 ; prepara espaço para novo bit12 sub r2, 30h ; r2 tem o valor do dígito: 0 ou 113 or r0, r11 ; monta novo bit com valor 114 add r12, 1 ; avança apontador15 sub r1, 1 ; chegou ao final da cadeia?16 jnz prox_dig ; não, trata mais dígitos17 ... ; sim, término; valor do byte em r0
Podemos melhorar esta solução notando que o resultado da instrução sub nalinha 12 é sempre zero ou um; dessa forma, podemos eliminar a necessidade do
66 CAPÍTULO 3. O PROCESSADOR FAÍSKA
desvio condicional da linha 13:
1 ; trecho para calcular valor binário representado por uma2 ; cadeia de caracteres ’0’ e ’1’ apontada por r123 ; segunda versão45 set r1, 8 ; vamos usar como contador6 xor r0, r0 ; r0 será usado como temporário7 ; vamos montar valor bit a bit8 prox_dig:9 ldb r2, (r12) ; r2 tem dígito: 30h ou 31h
10 shl r0, 1 ; prepara espaço para novo bit11 sub r2, 30h ; r2 tem o valor do dígito: 0 ou 112 or 0, r2 ; monta novo bit com valor 0 ou 113 add r12, 1 ; avança apontador14 sub r1, 1 ; chegou ao final da cadeia?15 jnz prox_dig ; não, trata mais dígitos16 ... ; sim, término; valor do byte em r0
Ainda uma outra versão, desta vez usando operações de rotação com o bit deestado C para diminuir ainda mais o número de instruções do loop nas linhas 8∼15:
1 ; trecho para calcular valor binário representado por uma2 ; cadeia de caracteres ’0’ e ’1’ apontada por r123 ; terceira versão45 set r1, 8 ; vamos usar r1 como contador6 xor r0, r0 ; r0 será usado como temporário7 ; vamos montar valor bit a bit8 prox_dig:9 ldb r2, (r12) ; r2 tem dígito: 30h ou 31h, coloca
10 rcr r2, r1 ; novo bit 0 ou 1 no bit vai-um11 rcl r0, 1 ; monta novo bit12 add r12, 1 ; avança apontador13 sub r1, 1 ; chegou ao final da cadeia?14 jnz prox_dig ; não, trata mais dígitos15 ... ; sim, término; valor do byte em r0