NEANDERWIN - Resumo operacional Sumário Listagem geral das instruções... 2 NOP... 2 LDI imed... 2 STA ender... 2 LDA ender... 3 ADD ender... 3 SUB ender... 3 OR ender... 4 AND ender... 4 NOT... 4 JMP ender... 5 JN ender... 5 JZ ender... 6 JNZ ender... 6 IN ender... 6 OUT ender... 7 HLT... 7 Modos de Endereçamento:... 7 imediato... 7 direto... 7 indireto... 8 Comentários no programa... 8 Rótulos... 8 Pseudo Instruções... 8 ORG ender... 8 const EQU imed... 8 END ender... 8 [var:] DB imed... 8 [var:] DS imed... 9 Representação de números... 9 ANEXO 1 simulador... 9 ANEXO 2 tabela ASCII... 10 ANEXO 3 exemplos... 11 Multiplicação... 11 Divisão... 11 Vetor... 11 ANEXO 4 referências... 12 1
Listagem geral das instruções Todas as instruções ocupam 1 byte. Algumas instruções possuem um operando que ocupa um segundo byte. Nas instruções, o código da operação ocupa os 4 bits de mais alta ordem, enquanto que os demais bits (mais baixa ordem) indicam o tipo de endereçamento da instrução. Instruções de 1 byte: código da instrução 0 (zero) Instruções de 2 bytes: código da instrução tipo de endereçamento operando NOP NOTA: apesar das instruções poderem ser escritas a partir da primeira coluna, é uma boa prática que sejam escritas a partir da coluna 7 (6 espaços) para melhor visualização. Essa área deve ser então utilizada para os rótulos (ver pág. 8) ou nome de identificador da pseudo-instrução EQU (pág. 8). O comando NOP (no operation) é usado apenas para gastar tempo. NOP ;não faz nada LDI imed O comando LDI (load immediate) carrega no acumulador o valor dado pelo operando imed. Endereçamento: imediato. LDI 10 ;ACC=10 DEZ LDI DEZ ;ACC=10 EQU 10 ;define constante=10 LDI VAR ;ACC=@VAR (20h) ORG 20h ;mem. a partir da posição 20h VAR: DB 10 ;declara variável, valor=10 STA ender O comando STA (store ACC) guarda o acumulador na posição de memória indicada pelo operando ender. STA 10 ;memória posição 10=ACC STA A ;memória posição[a]=acc ORG 10 ;mem. a partir da posição 10 A: DS 1 ;declara variável (1 byte) 2
STA @A ;memória posição[@a]=acc ORG 20h ;mem. a partir da posição 10 A: DB 21h ;declara variável, valor=21h LDA ender O comando LDA (load ACC) atribui ao acumulador o conteúdo da posição de memória indicada pelo operando ender. LDA 1 ;ACC=memória posição 1 LDA B ;ACC=memória posição[b] B: DB 10 ;declara variável, valor=10 LDA @B ;ACC=memória posição[@b] A: DB 5 ;declara variável, valor=5 B: DB 20h ;declara variável, valor=20h ADD ender O comando ADD soma (add) ao acumulador o conteúdo de uma posição de memória indicada pelo operando ender. LDI 1 ;ACC=1 ADD X ;ACC=ACC+memória posição[x] X: DB 10 ;declara variável, valor=10 ADD @Y ;ACC=ACC+memória posição[@y] X: DB 5 ;declara variável, valor=5 Y: DB 20h ;declara variável, valor=20h SUB ender O comando SUB (subtract) subtrai do acumulador o conteúdo de uma posição de memória indicada pelo operando ender. LDI 15 ;ACC=15 SUB X ;ACC=ACC-memória posição[x] X: DB 10 ;declara variável, valor=10 3
SUB @Y ;ACC=ACC-memória posição[@y] X: DB 5 ;declara variável, valor=5 Y: DB 20h ;declara variável, valor=20h OR ender O comando OR (logical or) realiza um "ou" lógico entre o acumulador e o conteúdo de uma posição de memória indicada pelo operando ender. O resultado é armazenado no acumulador. NOTA: a operação lógica é realizada bit a bit de acordo com a seguinte tabela: ACC Memória resultado (ACC) 0 0 0 0 1 1 1 0 1 1 1 1 LDI 0Fh ;ACC=0Fh (15) OR X ;ACC=ACC OU memória posição[x] X: DB 33h ;declara variável, valor=33h (51) LDI 0Fh ;ACC=0Fh (15) OR @Y ;ACC=ACC 'OU' memória posição[@y] X: DB 33h ;declara variável, valor=33h (51) Y: DB 20h ;declara variável, valor=20h AND ender O comando AND (logical and) realiza um "e" lógico entre o acumulador e o conteúdo de uma posição de memória indicada pelo operando ender. O resultado é armazenado no acumulador. NOTA: a operação lógica é realizada bit a bit de acordo com a seguinte tabela: ACC Memória resultado (ACC) 0 0 0 0 1 0 1 0 0 1 1 1 Essa instrução é conhecida como máscara, pois deixa passar os bits marcados com 1. LDI 0Fh ;ACC=0Fh (15) AND X ;ACC=ACC E memória posição[x] X: DB 33h ;declara variável, valor=33h (51) LDI 0Fh ;ACC=0Fh (15) AND @Y ;ACC=ACC 'E' memória posição[@y] X: DB 33h ;declara variável, valor=33h (51) Y: DB 20h ;declara variável, valor=20h NOT O comando NOT (logical not) inverte os bits do acumulador. NOTA: a operação lógica é realizada bit a bit de acordo com a seguinte tabela: 4
JMP ender ACC resultado (ACC) 0 1 1 0 LDI 0Fh ;ACC=0Fh (15) NOT ;ACC=bits invertidos O comando JMP (jump) desvia a execução do programa para o endereço indicado pelo operando ender. NOTA: os exemplos a seguir executam indefinidamente (não tem fim), servindo apenas como exemplo do funcionamento da instrução JMP. LDI 0 ;ACC=0 LOOP: ADD UM ;ACC=ACC+memória posição[um] JMP LOOP ;pula para LOOP LDI LOOP ;ACC=posição LOOP STA PULO ;memória posição[pulo]=acc LDI 0 ;ACC=0 LOOP: ADD UM ;ACC=ACC+memória posição[um] JMP @PULO ;pula para @PULO PULO: DS 1 ;declara variável (1 byte) JN ender O comando JN (jump if negative) desvia a execução do programa para o endereço indicado pelo operando ender apenas quando a última operação realizada produziu um valor com o bit 7 ligado (negativo). LDI 5 ;ACC=5 LOOP: SUB UM ;ACC=ACC-memória posição[um] JN FIM ;pula para FIM se bit 7(ACC)=1 JMP LOOP ;pula para LOOP FIM: LDI 0 ;ACC=0 SUB TRES ;ACC=ACC-memória posição[tres] LOOP: ADD UM ;ACC=ACC+memória posição[um] JN LOOP ;pula para LOOP se bit 7(ACC)=1 TRES: DB 3 ;declara variável, valor=3 5
JZ ender LDI LOOP ;ACC=posição LOOP STA PULO ;memória posição[pulo]=acc LDI 0 ;ACC=0 SUB TRES ;ACC=ACC-memória posição[tres] LOOP: ADD UM ;ACC=ACC+memória posição[um] JN @PULO ;pula para @PULO se bit 7(ACC)=1 TRES: DB 3 ;declara variável, valor=3 PULO: DS 1 ;declara variável (1 byte) O comando JZ (jump if zero) desvia a execução do programa para o endereço indicado pelo operando ender, apenas quando a última operação realizada produziu um valor zero. LDI 5 ;ACC=5 LOOP: SUB UM ;ACC=ACC-memória posição[um] JZ FIM ;pula para FIM se ACC=0 JMP LOOP ;pula para LOOP FIM: LDI FIM ;ACC=posição FIM STA PULO ;memória posição[pulo]=acc LDI 5 ;ACC=5 LOOP: SUB UM ;ACC=ACC-memória posição[um] JZ @PULO ;pula para @PULO se ACC=0 JMP LOOP ;pula para LOOP FIM: PULO: DS 1 ;declara variável (1 byte) JNZ ender O comando JNZ (jump if not zero) desvia a execução do programa para o endereço indicado pelo operando ender, apenas quando a última operação realizada produziu um valor diferente de zero. LDI 5 ;ACC=5 LOOP: SUB UM ;ACC=ACC-memória posição[um] JNZ LOOP ;pula para LOOP se ACC<>0 LDI LOOP ;ACC=posição LOOP STA PULO ;memória posição[pulo]=acc LDI 5 ;ACC=5 LOOP: SUB UM ;ACC=ACC-memória posição[um] JNZ @PULO ;pula para @PULO se ACC<>0 PULO: DS 1 ;declara variável (1 byte) IN ender O comando IN (input) traz para o acumulador o valor lido num dispositivo externo indicado pelo operando ender. Os dispositivos são: endereço 0: valor das chaves endereço 1: status de "dado disponível" das chaves. 6
LAB1: IN 1 ;verifica se o valor está disponível JZ LAB1 ;fica em loop IN 0 ;ACC=valor lido LAB1: IN DISP ;verifica se o valor está disponível JZ LAB1 ;fica em loop IN LEIT ;ACC=valor lido DISP EQU 1 ;define constante=1 LEIT EQU 0 ;define constante=0 OUT ender O comando OUT (output) descarrega o conteúdo do acumulador em um dispositivo externo indicado pelo operando ender. Os dispositivos disponíveis são: HLT endereço 0: descarrega no visor (hexadecimal) endereço 2: descarrega no banner o caracter ASCII cujo código está no acumulador (ver anexo). endereço 3: limpa o banner LDI 32 ;ACC=32 V: OUT 0 ;visor=acc OUT 2 ;banner=acc OUT 3 ;limpa banner ADD UM ;ACC=ACC+1 JMP V ;pula para V ORG 100 ;mem. a partir da posição 100 LDI 83 ;ACC=63 ('S') OUT 2 ;banner=acc LDI 105 ;ACC=63 ('i') OUT 2 ;banner=acc LDI 109 ;ACC=63 ('m') OUT 2 ;banner=acc LDI 33 ;ACC=63 ('!') OUT 2 ;banner=acc O comando HLT (halt) para a máquina. Modos de Endereçamento: imediato O segundo byte da instrução é o operando. A única instrução que usa este modo de endereçamento é a LDI. direto O segundo byte da instrução é o endereço de memória do operando. 7
indireto STA A ;memória posição[a]=acc ORG 10 ;mem. a partir da posição 10 A: DS 1 ;declara variável (1 byte) O segundo byte da instrução contém o endereço de memória onde está o endereço do operando (ou seja, o segundo byte da instrução é o endereço do ponteiro para o operando). Para indicar que um operando é indireto, deve-se precedê-lo pela letra "@" (arrôba). LDA @B ;ACC=memória posição[@b] A: DB 5 ;declara variável, valor=5 B: DB 20h ;declara variável, valor=20h Comentários no programa Os comentários começam ; (ponto e vírgula) e podem também ocorrer no final das linhas de instruções. LDI 10 ;ACC=10 Rótulos Um rótulo é um nome dado à próxima posição de memória. O nome é seguido por dois pontos. LDA B ;ACC=memória posição[b] B: DB 10 ;declara variável, valor=10 Pseudo Instruções ORG ender A pseudo-instrução ORG (origin) indica ao montador que a próxima instrução será colocado na posição ender de memória. STA A ;memória posição[a]=acc ORG 10 ;mem. a partir da posição 10 A: DS 1 ;declara variável (1 byte) const EQU imed A pseudo-instrução EQU (equate) atribui um nome (rótulo) a um certo valor, identificando assim uma constante. LDI DEZ ;ACC=10 DEZ EQU 10 ;define constante=10 END ender A pseudo-instrução END indica que o programa fonte acabou. O operando ender é usado para pré-carregar o PC com o endereço inicial de execução do programa. Essa pseudo-instrução é opcional. [var:] DB imed A pseudo-instrução DB (define byte) carrega a memória (byte) com o valor dado pelo operando imed. 8
Quando [var] (opcional) é definido, pode ser usado para referenciar a posição de memória reservada. LDA B ;ACC=memória posição[b] B: DB 10 ;declara variável, valor=10 Normalmente essa pseudo-instrução não é útil sem a referência var. Essa pseudo-instrução, apesar de pouco comum, pode ser usada no meio das instruções, o que deve ser feito com muito cuidado e atenção, pois os resultados podem ser imprevisíveis. LDA B ;ACC=memória posição[b] DB 0F0h ;declara variável, valor=0f0h (HLT) B: DB 10 ;declara variável, valor=10 [var:] DS imed A pseudo-instrução DS (define storage) reserva um número de palavras na memória definido pelo valor imed. Quando [var] (opcional) é definido, pode ser usado para referenciar a posição de memória reservada. STA A ;memória posição[a]=acc ORG 10 ;mem. a partir da posição 10 A: DS 1 ;declara variável (1 byte) Normalmente essa pseudo-instrução não é útil sem a referência var. Essa pseudo-instrução, apesar de pouco comum, pode ser usada no meio das instruções, o que deve ser feito com muito cuidado e atenção, pois os resultados podem ser imprevisíveis. LDI 5 ;ACC=5 STA OP ;memória posição[op]=acc DB 0E0h ;declara variável, valor=0e0h (LDI) OP: DS 1 ;declara variável (1 byte) Representação de números Decimal: 30 Binário: 00110000b Hexadecimal: 30h Nota: Números hexadecimais maiores que 7Fh devem ser precedidos por um zero, p. ex. 0F3h ANEXO 1 simulador O NeanderWin é um simulador da máquina Neander, definida no livro Fundamentos de Arquitetura de Computadores, Raul F. Weber (UFRGS), Ed. Sagra Luzzatto. A máquina original foi estendida para incluir algumas instruções extras, incluindo a carga de dados imediatos no acumulador e operações de entrada e saída de dados. Nesse simulador estão mapeados apenas dois dispositivos: um teclado e um visor. Cada instrução ocupa 1 byte. Na parte mais alta está o código da instrução propriamente dito. A parte mais baixa indica se a instrução usa endereçamento direto (0) ou indireto (1). Instrução operando código Descrição ADD ender 30h 31h AND ender 50h 51h HLT F0h parada da máquina. soma ao acumulador o conteúdo de [ender] ou de [@ender]. "e" lógico entre o acumulador e o conteúdo de [ender] ou de [@ender]. IN ender C0h traz para o acumulador o valor lido num dispositivo externo indicado por [ender]. 0 = valor das chaves 1 = status de "dado disponível" nas chaves 9
JMP ender 80h 81h JN ender 90h 91h JNZ ender B0h B1h JZ ender A0h A1h LDA ender 20h 21h desvia a execução do programa para o endereço ender ou [@ender]. desvia a execução do programa para o endereço ender ou @ender SE a última operação realizada produziu um valor com o bit 7 ligado (negativo). desvia a execução do programa para o endereço ender ou @ender SE a última operação realizada produziu um valor diferente de zero. desvia a execução do programa para o endereço ender ou @ender SE a última operação realizada produziu um valor zero. atribui ao acumulador o conteúdo de [ender] ou de [@ender] LDI imed E0h carrega no acumulador o valor dado pelo operando imed. NOP 00h gastar tempo. NOT 60h inverte os bits do acumulador. OR ender 40h 41h "ou" lógico entre o acumulador e o conteúdo de [ender] ou de [@ender]. OUT ender E0h descarrega o acumulador no dispositivo externo indicado por ender. 0 = visor 2 = banner para escrever o dado do ACC 3 = limpar STA ender 10h 11h SUB ender 70h 71h guarda o acumulador na posição ender ou @ender subtrai do acumulador o conteúdo de [ender] ou de [@ender]. ANEXO 2 tabela ASCII DEC HEX CARAC DEC HEX CARAC DEC HEX CARAC DEC HEX CARAC 32 20 espaço 56 38 8 80 50 P 104 68 h 33 21! 57 39 9 81 51 Q 105 69 i 34 22 " 58 3ª : 82 52 R 106 6A j 35 23 # 59 3B ; 83 53 S 107 6B k 36 24 $ 60 3C < 84 54 T 108 6C l 37 25 % 61 3D = 85 55 U 109 6D m 38 26 & 62 3E > 86 56 V 110 6E n 39 27 ' 63 3F? 87 57 w 111 6F o 40 28 ( 64 40 @ 88 58 X 112 70 p 41 29 ) 65 41 A 89 59 Y 113 71 q 42 2A * 66 42 B 90 5A Z 114 72 r 43 2B + 67 43 C 91 5B [ 115 73 s 44 2C, 68 44 D 92 5C \ 116 74 t 45 2D - 69 45 E 93 5D ] 117 75 u 46 2E. 70 46 F 94 5E ^ 118 76 v 47 2F / 71 47 G 95 5F _ 119 77 w 48 30 0 72 48 H 96 60 ` 120 78 x 49 31 1 73 49 I 97 61 a 121 79 y 50 32 2 74 4A J 98 62 b 122 7A z 51 33 3 75 4B K 99 63 c 123 7B { 52 34 4 76 4C L 100 64 d 124 7C 53 35 5 77 4D M 101 65 e 125 7D } 54 36 6 78 4E N 102 66 f 126 7E ~ 55 37 7 79 4F O 103 67 g 127 7F DEL 10
ANEXO 3 exemplos Multiplicação Exibe o resultado N1 x N2 VLT: LDA MLT ;MLT=MLT+N1 ADD N1 STA MLT LDA N2 ;N2=N2-1 SUB UM STA N2 JNZ VLT ;volta se ACC<>0 LDA MLT ;exibe MLT OUT 0 Divisão UM: DB 1 N1: DB 5 N2: DB 4 MLT: DB 0 ;resultado Exibe o resultado da divisão inteira de N1 por N2. No final ACC=resto da divisão. LDA N1 STA RST VLT: LDA DIV ADD UM STA DIV LDA RST SUB N2 JN FIM STA RST JMP VLT FIM: LDA DIV ;exibe DIV OUT 0 LDA RST Vetor UM: DB 1 N1: DB 22 N2: DB 4 DIV: DB 0FFh ;resultado RST: DS 1 ;resto O vetor (VET) é delimitado pelo valor 0FFh (-1). É exibido o valor da soma dos elementos do vetor. 11
VLT: LDI VET ;ENDR=VET[IND] ADD IND STA ENDR LDA @ENDR ;ACC=@ENDR JN FIM ;ACC<0? ADD SOMA ;SOMA=SOMA+ACC STA SOMA LDA IND ;IND=IND+1 ADD UM STA IND JMP VLT ;volta FIM: LDA SOMA ;exibe SOMA OUT 0 UM: DB 1 IND: DB 0 ENDR: DS 1 SOMA: DB 0 VET: DB 2 DB 4 DB 6 DB 8 DB 0FFh ANEXO 4 referências http://equipe.nce.ufrj.br/gabriel/estacio/maquinaneander.pdf http://www.ppgee.pucminas.br/weac/2006/pdf/weac-2006-artigo-05.pdf http://www.dcc.ufrj.br/~gabriel/weac2006.pdf 12