DEPARTAMENTO DE CIÊNCIA DA COMPUTAÇÃO
INSTITUTO DE CIÊNCIAS EXATAS
UNIVERSIDADE FEDERAL DE MINAS GERAIS
Simulador Funcional µRISC
1 Introdução *
2 Implementação do Simulador para o µRISC *
2.1.2 Constantes *
2.1.3 Transferência de controle *
2.1.4 Memória *
2.1.5 NOP *
2.1.6 Condição de término *
2.2 Sintaxe de chamada *
3.2 O que deve ser entregue *
5 Apêndice A: Formato do arquivo de entrada do montador *
5.2 Formato do arquivo de entrada *
5.3 Usando o montador e o linker *
5.4 Bugs *
6.2 Descrição do formato *
6.3 Exemplo de um arquivo de instruções *
7.2 Listagem do arquivo teste1 *
8.2 SOMA INTEIRA COM INCREMENTO *
8.3 AND LÓGICO *
8.4 NOT ra e AND LÓGICO *
8.5 SHIFT ARITMÉTICO PARA A ESQUERDA *
8.6 SHIFT ARITMÉTICO PARA A DIREITA *
8.7 DECREMENTO *
8.8 INCREMENTO *
8.9 JUMP INCONDICIONAL *
8.10 JUMP AND LINK *
8.11 JUMP FALSE *
8.12 JUMP REGISTER *
8.13 JUMP TRUE *
8.14 CARREGA CONSTANTE NO BYTE MAIS SIGNIFICATIVO *
8.15 CARREGA CONSTANTE NO BYTE MENOS SIGNIFICATIVO *
8.16 LOAD WORD *
8.17 CARREGA CONSTANTE DE 11 BITS COM SINAL *
8.18 SHIFT LÓGICO PARA A ESQUERDA *
8.19 SHIFT LÓGICO PARA A DIREITA *
8.20 NAND LÓGICO *
8.21 NOR LÓGICO *
8.22 ONES *
8.23 OR LÓGICO *
8.24 NOT rb e OR LÓGICO *
8.25 COPIA ra *
8.26 NOT ra *
8.27 STORE WORD *
8.28 SUBTRAÇÃO INTEIRA *
8.29 SUBTRAÇÃO INTEIRA COM DECREMENTO *
8.30 XNOR LÓGICO *
8.31 XOR LÓGICO *
8.32 ZERA *
Este trabalho visa a implementação de um simulador funcional para um processador RISC de 16 bits, o µRISC. Este processador possui 8 registradores de uso geral e 32 instruções.
Cada instrução executada no µRISC demora quatro ciclos para completar, embora quatro instruções possam ser executadas simultaneamente (caso a implementação seja em pipeline). Estes ciclos são denominados: IF, ID, EX/MEM e WB.
2. Implementação do Simulador para o µRISC
O processador µRISC deverá possuir as seguintes características:
Um dos requisitos fundamentais para se entender como implementar o
simulador funcional do processador µRISC é a compreensão do termo "funcional" .
Uma descrição funcional divide o processador nos blocos que existirão em uma
implementação real. Portanto, o processador deverá conter quatro rotinas
principais, uma para cada etapa do ciclo a ser executado em cada instrução. Note
que a única forma de comunicação entre essas quatro rotinas em um processador
real é via registradores, que no caso do simulador serão implementados por
estruturas de dados no programa do simulador.
Além dessas quatro rotinas, os elementos principais do processador real deverão estar encapsulados por módulos, tais como os elementos, banco de registradores, ALUs, incrementadores e memória.
A implementação deve ser feita na linguagem C.
As instruções de ALU seguem o seguinte formato:
Formato I:
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
|
|
|
|
|
| |||||
|
|
|
|
| 00000 | C = 0 | zeros c |
| 00010 | C = A & B | and c,a,b |
| 01010 | C = (~A) & B | andnota c,a,b |
| 01001 | C = A | passa c,a |
| 00110 | C = A ^ B | xor c,a,b |
| 00100 | C = A | B | or c,a,b |
| 00101 | C = ~(A | B) | nor c,a,b |
| 00111 | C = ~(A ^ B) | xnor c,a,b |
| 01000 | C = ~A | passnota c,a |
| 01011 | C = A | ~B | ornotb c,a,b |
| 00011 | C = ~(A & B) | nand c,a,b |
| 00001 | C = 1 | ones c |
| 11000 | C = A + B | add c,a,b |
| 11010 | C = A + B + 1 | addinc c,a,b |
| 11100 | C = A + 1 | inca c,a |
| 11011 | C = A - B - 1 | subdec c,a,b |
| 11001 | C = A - B | sub c,a,b |
| 11101 | C = A - 1 | deca c,a |
| 10000 | C = shift lógico para a esquerda | lsl c,a |
| 10010 | C = shift lógico para a direita | lsr c,a |
| 10011 | C = shift aritmético para a direita | asr c,a |
| 10001 | C = shift aritmético para a esquerda | asl c,a |
Todas as instruções de ALU alteram os valores dos flags do processador: neg, zero, negzero, carry, overflow, true. As instruções lógicas, como and e or, zeram os flags overflow e carry. Veja a descrição das instruções no Apêndice D para maiores detalhes.
O processador µRISC possui somente instruções para a carga de
constantes com sinal, representadas pelas instruções indicadas abaixo:
|
|
|
|
|
|
C = Constante | loadlit c, Const11
lc c, Const11 |
|
|
C = Const8 | (C & 0xff00) | lcl c, Const8 |
|
|
C = (Const8 << 8) | (C & 0x00ff) | lch c, Const8 |
Formato II:
| 15 |
14 |
13 |
11 |
10 |
0 |
|
|
|
| |||
Formato III:
| 15 |
14 |
13 |
11 |
|
9 |
8 |
7 |
0 |
|
|
|
|
|
| ||||
|
|
|
|
|
|
|
|
|
Na instrução loadlit, antes de ser carregada em um registrador, a constante precisa ter primeiro seu sinal estendido.
Para estender uma constante com sinal de k bits (de 0 a
k-1) para n (n > k) bits, copia-se o bit
k-1 da constante (ou seja, o bit de sinal) para os bits k a
n-1 da nova constante. Exemplo: seja a constante de 8 bits com
sinal 11110101. Em 16 bits, esta constante é representada como
1111111111110101. Já a constante 01110101 é representada como
0000000011110101.
O processador µRISC possui cinco instruções para a transferência de
controle, codificadas de três maneiras diferentes, que são indicadas
abaixo. A primeira codificação é utilizada para instruções de desvios
condicionais (onde o desvio é relativo ao PC e de comprimento de 8 bits) e
a segunda codificação é utilizada para a instrução de desvios
incondicionais (onde o desvio é também relativo ao PC e de comprimento de
12 bits).
Formato IV:
| 15 |
14 |
13 |
12 |
11 |
8 |
7 |
0 |
|
|
|
|
| ||||
Formato V:
| 15 |
14 |
13 |
12 |
11 |
0 |
|
|
|
| |||
| 15 |
14 |
13 |
12 |
|
10 |
3 |
2 |
0 |
|
|
|
|
|
| ||||
|
|
|
|
|
|
|
|
Jump False | jf.cond Destino |
|
|
|
Jump True | jt.cond Destino |
|
|
|
Jump Incondicional | j Destino |
|
|
|
Jump and Link | jal b |
|
|
|
Jump Register | jr b |
|
|
|
|
|
Jump and Link |
|
|
Jump Register |
|
|
|
|
|
|
Resultado ALU negativo | .neg |
|
|
Resultado ALU zero | .zero |
|
|
Carry da ALU | .carry |
|
|
Resultado ALU negativo ou zero | .negzero |
|
|
Resultado ALU diferente de zero | .true |
|
|
Resultado ALU overflow | .overflow |
Nas instruções de Jump True, Jump False e Jump o
desvio é relativo ao PC. O endereço da próxima instrução a ser executada,
caso o Jump seja realizado, é o valor do PC incrementado de 1 mais
a constante estendida de sinal. Assim, no ciclo EX/MEM, esse endereço pode
ser obtido somente somando o PC com a constante, pois nesse ciclo o PC já
foi incrementado de um.
Formato VII:
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
|
|
|
|
|
| |||||
| OPbin | Operação | Mnemônico |
| 10100 | C = Mem[A] | load c, a
ld c, a |
| 10110 | Mem[A] = B | store a, b
st a, b |
Diversas instruções podem gerar NOPs. No caso, foi escolhida a condição jf.true 0x00, ou seja, uma instrução onde todos os 16 bits estão zerados.
O programa do simulador deve aceitar um mínimo de parâmetros e opções:
uRISC <arq_entrada> [-d <pos_inicial> <numero_palavras>] [-s] [-p],
onde :
-d : opção para pedido de dump memória a partir de <pos_inicial> (em hexadecimal) que deve imprimir então (na saída padrão) <numero_palavras> de palavras (em hexadecimal) sequencialmente. Essa operação deve ser executada no final da execução do arquivo de instruções;
-s : screen, opção para pedido de impressão na saída padrão de um resumo do estado do processador após a execução de cada instrução;
-p : opção que faz pausar a impressão cada vez que a tela 'enche' esperando que alguma tecla seja acionada.
turmalina:~-> uRISC teste1
# execução com pedido de dump de 1 palavra a partir da posição 1000 #
turmalina:~-> uRISC teste1 -d 03e8 1
# execução com pedido de dump e de screen #
turmalina:~-> uRISC teste1 -d 03e8 1 -s
# execução anterior com pedido de pausa #
turmalina:~-> uRISC teste1 -d 03e8 1 -s -p
# execução com pedido de screen com pausa #
turmalina:~-> uRISC teste1 -s -p
-----------------------------------------------------------------------
Status do Processador
REGISTRADORES Flags
Reg00 = 0000 Neg 0
Reg01 = 00aa Zero 1
Reg02 = 0190 Carry 0
Reg03 = 7fff NegZero 0
Reg04 = 23e0 Overflow 1
Reg05 = 7caf
Reg06 = 0010
Reg07 = 0015
PC = 00a1
IR = 8807
Instrução executada = 00a0
----------------------------------------------------------------------
NOTA: Deve-se ter uma atenção toda especial para a saída do dump, uma
vez que esse será utilizado para conferir o resultado do processamento. A opção
screen será de grande valia quando da depuração do programa e
acompanhamento da execução.
A documentação será de grande importância na avaliação de todo o trabalho. Não é necessário que seja extensa, porém deve ser completa.
Deve conter basicamente:
Outras informações relevantes do projeto também devem constar da
documentação.
Assim, tendo em vista toda a importância dos testes no projeto, eles devem ser apresentados juntos com a documentação. Deve-se, também, explicar os motivos pelos quais aqueles testes foram usados e sua utilidade. Como sugestão de testes úteis, temos:
No dia da entrega do trabalho devem ser apresentados:
[1] D.A. Patterson and J. L. Hennessy. Computer Organization & Design
- The Hardware/Software Interface. Morgan Kaufmann Publishers, Inc.,
1994.
[2] Philip M. Sailer and David R. Kaeli. The DLX Instruction Set Architecture Handbook. Morgan Kaufmann Publishers, Inc., 1996.
5. Apêndice A: Formato do
arquivo de entrada do montador
Esta seção visa fornecer as informações necessárias para escrever programas
em linguagem de montagem para o processador µRISC. Os arquivos executáveis do
montador e do linker serão fornecidos para converter o programa em linguagem
de montagem para linguagem de máquina. A seguir serão apresentadas as
convenções utilizadas pelo montador.
int soma(int reg1, int reg2)
{
return reg1 +
reg2;
}
void main()
{
static int resultado = 8;
static int teste;
int a = 500;
int b = 10000;
resultado = soma(a, b);
}
Uma das várias formas de se escrever este mesmo programa em linguagem de montagem é apresentada a seguir:
; Nome deste programa: TESTE1.ASM
Neste programa, podemos observar as seguintes convenções:
Existem também alguns alias para números de registradores:
Observar que os espaços em branco são ignorados. Ou seja, as
instruções
loadlit r4, 9
loadlit r4,9
são idênticas.
Usa-se geralmente estas duas palavras (LOWBYTE e HIGHBYTE) para se carregar
uma constante de 16 bits em um registrador através das instruções lcl e
lch. Os dois trechos de código abaixo são um exemplo:
lcl r1, LOWBYTE 10000
lch r1, HIGHBYTE 10000
; ....
lcl
r1, LOWBYTE L3
lch r1, HIGHBYTE L3
Nas duas primeiras instruções, a constante 10000 é carregada no registrador
r1, enquanto nas duas últimas instruções o valor de L3 (ou seja, a posição de
memória que este rótulo referencia) é carregado no registrador r1.
Outro exemplo:
L2: ; variável1 L2: ;
variável1
.const -1 .blk 1
lcl r0, LOWBYTE _soma ; carrega o endereço da função soma
lch r0, HIGHBYTE _soma ; no registrador r0
jal r0 ; chama a função soma e salva o endereço de retorno em ra(ou r7)
Convém observar que toda função deve salvar o endereço de retorno e os
registradores que serão usados antes de executar qualquer outra operação. Além
disso, lembrar que estes valores devem ser restaurados no final da execução da
função. Veja exemplos no código do programa TESTE1.ASM.
O montador e o linker devem ser invocados utilizando os seguintes comandos em UNIX:
urasm input_file1.asm
urlink input_file1.obj input_file2.obj ... input_filen.obj <-onome_do_arquivo_executável>
O primeiro comando executa o montador usando como arquivo de entrada input_file1.asm e obtendo como saída um arquivo de nome input_file1.obj. No segundo comando, input_file1.obj é usado como arquivo de entrada para o linker, que completa a conversão do arquivo para linguagem de máquina, que deverá ser lido pelo simulador. O formato deste arquivo será descrito nas duas próximas páginas.
Obs.: O arquivo de entrada para o montador deve ter uma extensão .asm.
Exemplo: suponha que temos um arquivo em linguagem de montagem cujo nome é teste1.asm. Para convertê-lo para linguagem de máquina utilizaríamos os comandos:
urasm teste1.asm
urlink teste1.obj -oteste1
Neste caso o nome do arquivo executável seria teste1. Caso o nome do arquivo executável não fosse definido, o nome seria a.out por convenção.
Um dos arquivos (.obj) que serão usados para se construir o
arquivo de instruções (utilizando o linker) deve ter uma função
main (declarada através de .global _main), que indica onde o
programa deve iniciar a execução.
6. Apêndice B: Formato do arquivo de instruções
Esta seção define como deve ser o formato do arquivo de instruções para o processador µRISC. Convém salientar que o formato, que será descrito a seguir, deve ser adotado obrigatoriamente por todos os grupos.
Como especificado, a memória do processador possui 16 bits de
endereçamento, sendo endereçada por palavra. Ou seja, a memória pode
armazenar até 65536 palavras de 16 bits cada (os endereços vão de 0 a 65535
em decimal ou de 0x0000 a 0xffff em hexadecimal).
O formato do arquivo de instruções para o processador µRISC é bem simples. Podemos defini-lo através de apenas três características:
- O arquivo, em modo texto, deve conter apenas uma instrução por linha.
- As instruções devem estar codificadas em hexadecimal.
- A palavra-chave address pode ser usada para definir a partir de qual posição de memória as instruções devem ser armazenadas. A sintaxe é a seguinte:
address end
, onde end é um endereço de memória codificado em hexadecimal. Um
pequeno exemplo ilustra a utilidade desta palavra-chave. Seja o seguinte
arquivo de instruções hipotético:
address 00ff
b7ff
c041
address 1000
c868
2fff
Neste caso as instruções 0xb7ff e 0xc041 serão armazenadas nas posições de memória 0x00ff e 0x0100 respectivamente e as instruções 0xc868 e 0x2fff nas posições de memória 0x1000 e 0x1001 respectivamente.
Observar que, se a diretiva address não for usada para definir onde as instruções devem ser armazenadas, será considerado, por convenção, que as instruções serão colocadas a partir da posição 0x0000 de memória.
A seguir é apresentado um arquivo de instruções que obedece o formato
descrito no item 2.
address 0000
b7ff
c041
c400
3000
2fff
address 0041
a01d
980f
501c
3807
Veja o conteúdo de memória após o processador carregar o arquivo de
instruções acima:
|
|
|
|
|
| 0x0000 (Posição 0) |
|
0x0041 (Posição 65) |
|
| 0x0001 (Posição 1) |
|
0x0042 (Posição 66) |
|
| 0x0002 (Posição 2) |
|
0x0043 (Posição 67) |
|
| 0x0003 (Posição 3) |
|
0x0044 (Posição 68) |
|
| 0x0004 (Posição 4) |
|
Nesta seção é apresentado um teste para o µRISC. O teste é o arquivo teste10.asm (arquivo no formato de entrada do montador) que é listado a seguir.
O arquivo de entrada para o montador é o teste10.asm. O arquivo no formato de entrada do simulador é o arquivo teste10. O arquivo teste10.lis contem a listagem da montagem do código, sendo de grande utilidade na verificação do teste.
Se seu simulador do µRISC funcionar corretamente, no final da execução do teste10, a posição de memória 1000 (0x03e8 em hexadecimal) conterá o valor 10. Se isso ocorrer, ótimo! Seu simulador PARECE funcionar corretamente para uma parcela das instruções. Se seu simulador passar nesse teste, você não demonstrou que ele está totalmente correto. Faça mais testes até poder garantir isso.
Se seu simulador entrar em loop infinito, isso não é um bom sinal. Se no final da execução do teste10, o seu simulador conter um valor menor do que 10 na posição 1000 de memória, algumas instruções não estão funcionando corretamente. Siga a execução do teste (veja o arquivo teste10.lis) para descobrir o que está dando errado.
Vale lembrar novamente que os testes para a avaliação do simulador do µRISC serão exaustivos e abrangentes, e possivelmente detectarão qualquer erro no seu simulador. Garanta que ele funcione em qualquer caso.
Seguem abaixo as descrições das instruções
implementadas pelo processador µRISC.
|
15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
|
01 |
rc |
11000 |
ra |
rb | |||||
Tipo: I
Formato: add rc, ra, rb
Exemplo: add r3, r2, r1
Operação: rc = ra + rb
Descrição: Soma (aritmética) o conteúdo de ra com rb e coloca o resultado em rc.
Flags afetados: neg, zero, carry, overflow.
2. SOMA INTEIRA COM
INCREMENTO
addinc rc,ra,rb
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 11010 | ra | rb | |||||
Tipo: I
Formato: addinc rc, ra, rb
Exemplo: addinc r3, r2, r1
Operação: rc = ra + rb + 1
Descrição: Soma (aritmética) o conteúdo de ra com rb e adiciona 1, colocando o resultado em rc.
Flags afetados: neg, zero, carry, overflow.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 00010 | ra | rb | |||||
Tipo: I
Formato: and rc, ra, rb
Exemplo: and r3, r2, r7
Operação: rc = ra & rb
Descrição: Efetua and lógico bit a bit de ra com rb e coloca o resultado em rc.
Flags afetados: neg, zero. carry = 0. overflow = 0.
4. NOT ra e AND
LÓGICO
andnota rc,ra,rb
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 01010 | ra | rb | |||||
Formato: andnota rc, ra, rb
Exemplo: andnota r3, r2, r7
Operação: rc = (~ra) & rb
Descrição: Efetua and lógico bit a bit de ra (negado bit a bit) com rb e coloca o resultado em rc.
Flags afetados: neg, zero. carry = 0. overflow = 0.
5. SHIFT ARITMÉTICO PARA A ESQUERDA asl rc,ra
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 10001 | ra | X | |||||
Formato: asl rc, ra
Exemplo: asl r3, r2
Operação: rc = ra << 1
Descrição: Coloca cada bit rai em rci+1 e preenche com 0 a posição rc0.
Flags afetados: neg, zero. carry = ra15 e overflow = ra15 ^ ra14.
6. SHIFT ARITMÉTICO PARA A
DIREITA
asr rc,ra
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 10011 | ra | X | |||||
Formato: asr rc, ra
Exemplo: asr r3, r2
Operação: rc = ra >> 1
Descrição: Coloca cada bit rai em rci-1 (exceto ra0) e preenche com ra15 a posição rc15.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 11101 | ra | X | |||||
Formato: deca rc, ra
Exemplo: deca r3, r1
Operação: rc = ra - 1
Descrição: Subtrai 1 do conteúdo de ra e coloca o resultado em rc.
Flags afetados: neg, zero, carry, overflow.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 11100 | ra | X | |||||
Formato: inca rc, ra
Exemplo: inca r3, r1
Operação: rc = ra + 1
Descrição: Adiciona 1 ao conteúdo de ra e coloca o resultado em rc.
Flags afetados: neg, zero, carry, overflow.
9. JUMP
INCONDICIONAL
j Destino
| 15 |
14 |
13 |
12 |
11 |
0 |
| 00 | 10 | Offset12 | |||
Formato: j Destino
Exemplo: j loop
Operação: PC = (PC + 1) + Offset12EstendidoPara16Bits
Descrição: Realiza desvio de fluxo incondicional relativo ao PC. O endereço da próxima instrução a ser executada
será o novo PC (PC + 1) mais a constante de 12 bits (presente nos bits de 0 a 11 da instrução) estendida de sinal.
Flags afetados: Nenhum.
| 15 |
14 |
13 |
12 |
|
10 |
3 |
2 |
0 |
| 00 | 11 | 0 | X | rb | ||||
Formato: jal rb
Exemplo: jal r4
Operação: r7 = (PC + 1) e PC = rb
Descrição: Realiza chamadas a procedimentos guardando o endereço do PC (PC +1) no registrador r7
(para o retorno após o procedimento) e colocando em PC o valor de rb (primeira instrução do procedimento).
Flags afetados: Nenhum.
11. JUMP
FALSE
jf.cond Destino
| 15 |
14 |
13 |
12 |
11 |
8 |
7 |
0 |
| 00 | 00 | Cond | Offset8 | ||||
Formato: jf.cond offset8
Exemplo: jf.zero 10
Operação: se condição é falsa, PC = (PC + 1) + Offset8EstendidoPara16Bits
Descrição: Realiza desvio condicional relativo ao PC se a condição é falsa. O endereço
da próxima instrução a ser executada será o novo PC (PC + 1) mais a constante de 8 bits
(presente nos bits de 0 a 7 da instrução) estendida de sinal.
Flags afetados: Nenhum.
| CONDbin |
|
|
| 0100 | Resultado ALU negativo | .neg |
| 0101 | Resultado ALU zero | .zero |
| 0110 | Carry da ALU | .carry |
| 0111 | Resultado ALU negativo ou zero | .negzero |
| 0000 | Resultado ALU diferente de zero | .true |
| 0011 | Resultado ALU overflow | .overflow |
| 15 |
14 |
13 |
12 |
11 |
10 |
3 |
2 |
0 | |
| 00 | 11 | 1 | X | rb | |||||
Formato: jr rb
Exemplo: jr r7
Operação: PC = r7
Descrição: Armazena o conteúdo do registrador b em PC.
Flags afetados: Nenhum.
| 15 |
14 |
13 |
12 |
11 |
8 |
7 |
0 |
| 00 | 01 | Cond | Offset8 | ||||
Formato: jt.cond Destino
Exemplo: jt.true loop
Operação: se condição é verdadeira, PC = (PC + 1) + Offset8EstendidoPara16Bits
Descrição: Realiza desvio condicional relativo ao PC se a condição é verdadeira. O endereço
da próxima instrução a ser executada será o novo PC (PC + 1) mais a constante de 8 bits
(presente nos bits de 0 a 7 da instrução) estendida de sinal.
Flags afetados: Nenhum.
| CONDbin |
|
|
|
|
Resultado ALU negativo | .neg |
|
|
Resultado ALU zero | .zero |
|
|
Carry da ALU | .carry |
|
|
Resultado ALU negativo ou zero | .negzero |
|
|
Resultado ALU diferente de zero | .true |
|
|
Resultado ALU overflow | .overflow |
14. CARREGA CONSTANTE NO BYTE MAIS SIGNIFICATIVO lch c, Const8
| 15 |
14 |
13 |
11 |
10 | 9 |
8 |
7 |
0 |
| 11 | rc | 1 | X | Offset8 | ||||
Formato: lch rc, offset8
Exemplo: lch r3, offset8
Operação: rc = (offset8 << 8) | (rc & 0x00ff)
Descrição: Carrega no byte mais significativo de rc o conteúdo de Offset8.
Flags afetados: Nenhum.
15. CARREGA CONSTANTE NO BYTE MENOS
SIGNIFICATIVO lcl c,
Const8
| 15 |
14 |
13 |
11 |
10 | 9 |
8 |
7 |
0 |
| 11 | rc | 0 | X | Offset8 | ||||
Formato: lcl rc, offset8
Exemplo: lcl r3, offset8
Operação: rc = Offset8 | (rc & 0xFF00)
Descrição: Carrega no byte menos significativo de rc o conteúdo de Offset 8.
Flags afetados: Nenhum.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 10100 | ra | X | |||||
Formato: load rc, ra
Exemplo: load r3, r6
Operação: rc = memória [ra]
Descrição: Carrega no registrador c o conteúdo da memória endereçada pelo registrador a.
Flags afetados: nenhum.
17. CARREGA CONSTANTE DE 11 BITS COM
SINAL loadlit c, Const
| 15 |
14 |
13 |
11 |
10 |
0 |
| 10 | rc | Offset11 | |||
Formato: loadlit rc, offset11
Exemplo: loadlit r3, 1000
Operação: rc = Offset11EstendidoPara16Bits
Descrição: Carrega em rc o conteúdo de Offset11 estendido para 16 bits.
Flags afetados: Nenhum.
18. SHIFT LÓGICO PARA A
ESQUERDA
lsl rc,ra
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 10000 | ra | X | |||||
Formato: lsl rc, ra
Exemplo: lsl r3, r2
Operação: rc = ra << 1
Descrição: Coloca cada bit rai em rci+1 (exceto ra15) e preenche com 0 a posição rc0.
Flags afetados: neg, zero. carry = ra15. overflow = 0.
19. SHIFT LÓGICO PARA A
DIREITA
lsr rc,ra
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 10010 | ra | X | |||||
Formato: lsr rc, ra
Exemplo: lsr r3, r2
Operação: rc = ra >> 1
Descrição: Coloca cada bit rai em rci-1 (exceto ra0) e preenche com 0 a posição rc15.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 00011 | ra | rb | |||||
Formato: nand rc, ra, rb
Exemplo: nand r3, r2, r7
Operação: rc = ~(ra & rb)
Descrição: Efetua nand lógico bit a bit de ra com rb e coloca o resultado em rc.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 00101 | ra | rb | |||||
Formato: nor rc, ra, rb
Exemplo: nor r3, r2, r7
Operação: rc = ~(ra | rb)
Descrição: Efetua nor lógico bit a bit de ra com rb e coloca o resultado em rc.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 00001 | X | X | |||||
Tipo: I
Formato: ones rc
Exemplo: ones r1
Operação: rc = 1
Descrição: Faz conteúdo de rc valer 1.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 00100 | ra | rb | |||||
Formato: or rc, ra, rb
Exemplo: or r3, r2, r7
Operação: rc = ra | rb
Descrição: Efetua or lógico bit a bit de ra com rb e coloca o resultado em rc.
Flags afetados: neg, zero. carry = 0. overflow = 0.
24. NOT rb e OR
LÓGICO
ornotb rc,rb,rb
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 01011 | ra | rb | |||||
Formato: ornotb rc, ra, rb
Exemplo: ornotb r3, r2, r7
Operação: rc = ra | ~rb
Descrição: Efetua or lógico bit a bit de ra com not rb, colocando o resultado em rc.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 01001 | ra | X | |||||
Formato: passa rc, ra
Exemplo: passa r4, r3
Operação: rc = ra
Descrição: Faz conteúdo de rc igual ao conteúdo de ra.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 01000 | ra | X | |||||
Formato: passnota rc, ra
Exemplo: passnota r4, r3
Operação: rc = ~ra
Descrição: Faz conteúdo de rc valer o complemento do conteúdo de ra.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | X | 10110 | ra | rb | |||||
Formato: store ra, rb
Exemplo: store r3, r6
Operação: memória [ra] = rb
Descrição: Carrega na posição da memória endereçada pelo registrador a o conteúdo do registrador b.
Flags afetados: nenhum.
28. SUBTRAÇÃO
INTEIRA
sub rc,ra,rb
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 11001 | ra | rb | |||||
Formato: sub rc, ra, rb
Exemplo: sub r3, r2, r1
Operação: rc = ra - rb
Descrição: Subtrai o conteúdo de rb do conteúdo de ra e coloca o resultado em rc.
Flags afetados: neg, zero, carry, overflow.
29. SUBTRAÇÃO INTEIRA COM
DECREMENTO
subdec rc,ra,rb
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 11011 | ra | rb | |||||
Formato: subdec rc, ra, rb
Exemplo: subdec r3, r2, r1
Operação: rc = ra - rb - 1
Descrição: Subtrai o conteúdo de rb do conteúdo de ra e subtrai 1 da diferença, colocando o resultado em rc.
Flags afetados: neg, zero, carry e overflow.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 00111 | ra | rb | |||||
Formato: xnor rc, ra, rb
Exemplo: xnor r3, r2, r7
Operação: rc = ~(ra^rb)
Descrição: Efetua xnor lógico bit a bit de ra com rb e coloca o resultado em rc.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 00110 | ra | rb | |||||
Formato: xor rc, ra, rb
Exemplo: xor r3, r2, r7
Operação: rc = ra ^ rb
Descrição: Efetua xor lógico bit a bit de ra com rb e coloca o resultado em rc.
Flags afetados: neg, zero. carry = 0. overflow = 0.
| 15 |
14 |
13 |
11 |
10 |
6 |
5 |
3 |
2 |
0 |
| 01 | rc | 00000 | X | X | |||||
Formato: zeros rc
Exemplo: zeros r1
Operação: rc = 0
Descrição: Faz conteúdo de rc valer 0.
Flags afetados: neg = 0. zero = 1. carry = 0. overflow = 0.
Última modificação: 17/08/2004
Alessandro Mendes - ajmendes@dcc.ufmg.br