Cesar - características CESAR (As bases da civilização atual) Registradores • • • • 8 registradores (R0-R7) R7 = program counter (PC) R6 = stack pointer (SP) três bits para seleção de registrador • R7 e R6 tem funções específicas, mas também são de uso geral • • • • Largura de dados e endereços de 16 bits Dados representados em complemento de dois 8 registradores de uso geral de 16 bits (R0-R7) 1 registrador de estado com 4 códigos de condição: negativo (N), zero (Z), carry (C) e overflow (V) • 8 modos de endereçamento • instruções com 2, 1 e zero operandos • suporte para pilha (stack) Modos de endereçamento • • • • • • • • 000 = registrador 001 = registrador pós-incrementado 010 = registrador pré-decrementado 011 = indexado 100 = registrador indireto 101 = pós-incrementado indireto 110 = pré-decrementado indireto 111 = indexado indireto Endereçamento de memória • Arquitetura de 16 bits • Memória organizada em bytes (8 bits) • Big endian - byte mais significativo armazenado no endereço menor (PDP, Motorola, Cesar) • Little endian - byte menos significativo armazenado no endereço menor (Intel) • Exemplo: mem(128) = 0 mem(129) = 1 mem(130) = 2 • Cesar - sem restrições no endereçamento (par ou ímpar) Modo Registrador memória registradores R0 instrução operando R7 MOV R0, R1 R1 ← R0 1 Pós-incrementado memória registradores instrução Pré-decrementado R0 1 memória registradores instrução R0 1 endereço endereço 4 2 operando operando R7 R7 3 4 2 3 -2 +2 Mem(R1) ← R0; R1← R1 + 2 MOV R0, (R1)+ R1← R1 - 2 ;Mem(R1) ← R0 MOV R0, -(R1) Indexado Registrador indireto memória registradores instrução memória registradores instrução R0 R0 deslocamento endereço endereço operando operando R7 R7 + Mem(R1+ddd) ← R0 MOV R0, ddd(R1) Pós-incrementado indireto Pré-decrementado indireto memória registradores instrução 2 memória registradores instrução R0 1 Mem(R1) ← R0 MOV R0, (R1) R0 1 endereço 4 endereço endereço endereço 3 5 R7 R7 operando 5 4 operando 3 +2 MOV R0, ((R1)+) Mem(Mem(R1)) ← R0; R1← R1 + 2 2 -2 MOV R0, (-(R1)) R1← R1 - 2 ;Mem(Mem(R1)) ← R0 2 Exemplos Indexado indireto memória registradores R0 instrução deslocamento operando endereço R7 endereço + MOV R0, (ddd(R1)) Mem(Mem(R1+ddd)) ← R0 Endereçamento com PC (R7) MOV R0, R7 MOV R7, R0 MOV R0, (R7)+ MOV (R7)+, R0 MOV R0, -(R7) MOV -(R7), R0 MOV R0, ddd(R7) MOV ddd(R7), R0 MOV R0, (R7) MOV (R7), R0 MOV R0, ((R7)+) MOV ((R7)+), R0 MOV R0, (-(R7)) MOV (-(R7)), R0 MOV R0, (ddd(R7)) MOV (ddd(R7)), R0 R7 ← R0 R0 ← R7 Mem(R7) ← R0; R7← R7 + 2 R0 ← Mem(R7) ; R7← R7 + 2 R7← R7 - 2 ;Mem(R7) ← R0 R7← R7 - 2 ;R0 ← Mem(R7) Mem(R7+ddd) ← R0 R0 ← Mem(R7+ddd) Mem(R7) ← R0 R0 ← Mem(R7) Mem(Mem(R7)) ← R0; R7← R7 + 2 R0 ← Mem(Mem(R7)); R7← R7 + 2 R7← R7 - 2 ;Mem(Mem(R7)) ← R0 R7← R7 - 2 ; R0 ← Mem(Mem(R7)) Mem(Mem(R7+ddd)) ← R0 R0 ← Mem(Mem(R7+ddd)) Modo registrador CLR R0 R0 ← 0 Modo registrador indireto CLR (R0) Mem(R0) ← 0 Modo indexado CLR ddd(R0) Mem(R0+ddd) ← 0; Modo pós-incrementado CLR (R0)+ Mem(R0) ← 0 ; R0← R0 + 2 Modo pré-decrementado CLR -(R0) R0← R0 - 2 ; Mem(R0) ← 0 Modo indexado indireto CLR (ddd(R0)) Mem(Mem(R0+ddd)) ← 0 Modo pós-incrementado indireto CLR ((R0)+) Mem(Mem(R0)) ← 0; R0← R0 + 2 Modo pré-decrementado indireto CLR (-(R0)) R0← R0 - 2 ; Mem(Mem(R0)) ← 0 Endereçamento com PC (R7) MOV R0, R7 MOV R7, R0 MOV R0, (R7)+ MOV (R7)+, R0 MOV R0, -(R7) MOV -(R7), R0 MOV R0, ddd(R7) MOV ddd(R7), R0 MOV R0, (R7) MOV (R7), R0 MOV R0, ((R7)+) MOV ((R7)+), R0 MOV R0, (-(R7)) MOV (-(R7)), R0 MOV R0, (ddd(R7)) MOV (ddd(R7)), R0 Útil Pilha • Cresce dos endereços superiores para os inferiores • Ponteiro da pilha aponta para o dado no topo da pilha • Colocação de um dado na pilha (push) SP ← SP - 2 Mem(SP) ← dado • Retirada de um dado da pilha (pop) dado ← Mem(SP) SP ← SP + 2 R7 ← R0 R0 ← R7 Mem(R7) ← R0; R7← R7 + 2 R0 ← Mem(R7) ; R7← R7 + 2 R7← R7 - 2 ;Mem(R7) ← R0 R7← R7 - 2 ;R0 ← Mem(R7) Mem(R7+ddd) ← R0 R0 ← Mem(R7+ddd) Mem(R7) ← R0 R0 ← Mem(R7) Mem(Mem(R7)) ← R0; R7← R7 + 2 R0 ← Mem(Mem(R7)); R7← R7 + 2 R7← R7 - 2 ;Mem(Mem(R7)) ← R0 R7← R7 - 2 ; R0 ← Mem(Mem(R7)) Mem(Mem(R7+ddd)) ← R0 R0 ← Mem(Mem(R7+ddd)) Cuidado ! Não usar !! Pilha • Cresce dos endereços superiores para os inferiores • Ponteiro da pilha aponta para o dado no topo da pilha • Colocação de um dado na pilha (push) SP ← SP - 2 Mem(SP) ← dado MOV origem,-(R6) • Retirada de um dado da pilha (pop) dado ← Mem(SP) SP ← SP + 2 MOV (R6)+,destino 3 Endereçamento com SP (R6) Endereçamento com SP (R6) MOV R0, R6 MOV R0, (R6)+ MOV R0, -(R6) MOV R0, ddd(R6) MOV R0, (R6) MOV R0, ((R6)+) MOV R0, (-(R6)) MOV R0, (ddd(R6)) R6 ← R0 Mem(R6) ← R0; R6← R6 + 2 R6← R6 - 2 ;Mem(R6) ← R0 Mem(R6+ddd) ← R0 Mem(R6) ← R0 Mem(Mem(R6)) ← R0; R6← R6 + 2 R6← R6 - 2 ;Mem(Mem(R6)) ← R0 Mem(Mem(R6+ddd)) ← R0 MOV R0, R6 MOV R0, (R6)+ MOV R0, -(R6) MOV R0, ddd(R6) MOV R0, (R6) MOV R0, ((R6)+) MOV R0, (-(R6)) MOV R0, (ddd(R6)) R6 ← R0 Mem(R6) ← R0; R6← R6 + 2 R6← R6 - 2 ;Mem(R6) ← R0 Mem(R6+ddd) ← R0 Mem(R6) ← R0 Mem(Mem(R6)) ← R0; R6← R6 + 2 R6← R6 - 2 ;Mem(Mem(R6)) ← R0 Mem(Mem(R6+ddd)) ← R0 MOV (R6)+, R0 MOV -(R6), R0 MOV (R6), R0 R0 ← Mem(R6) ; R6← R6 + 2 R6← R6 - 2 ;R0 ← Mem(R6) R0 ← Mem(R6) MOV (R6)+, R0 MOV -(R6), R0 MOV (R6), R0 R0 ← Mem(R6) ; R6← R6 + 2 ; (POP) R6← R6 - 2 ;R0 ← Mem(R6) R0 ← Mem(R6) ; (COPIAR SEM REMOVER) Útil Cuidado ! Identificação da instrução: 4 bits mais significativos Código 0000 0001 e 0010 0011 0100 0101 0110 0111 1000 1001 a 1110 1111 Tipo instrução de NOP instruções sobre os códigos de condição instruções de desvio condicional instrução de desvio incondicional (JMP) instrução de controle de laço (SOB) instrução de desvio para subrotina (JSR) instrução de retorno de subrotina (RTS) instruções de um operando instruções de dois operandos instrução de parada (HLT) Não usar !! 7 NOP 0 0 0 0 0 x x x x 7 0 CCC 0 0 0 1 n z v c SCC 0 0 1 0 n z v c 1 1 1 x x x x 7 7 Bccc cccc 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 ; (PUSH) 0 HLT 1 JMP 0 1 0 0 x x x x x x m m m r r r 0 0 0 1 1 c c c c d d d d d d d d Condição de desvio BR (always) sempre verdadeira BNE (Not Equal) z=0 BEQ (EQual) z=1 BPL (PLus) n=0 BMI (MInus) n=1 BVC (oVerflow Clear) v=0 BVS (oVerflow Set) v=1 BCC (Carry Clear) c=0 BCS (Carry Set) c=1 BGE (Greater or Equal) n=v BLT (Less Than) n<>v BGT (GreaTer) n = v and z = 0 BLE (Less or Equal) n < > v or z = 1 BHI (HIgher) c = 0 and z = 0 BLS (Lower or Same) c = 1 or z = 1 7 0 mnemônico PC ← endereço de desvio (modo 0 = NOP) 7 SOB 0 0 1 0 1 x r r r d d d d d d d d r ← r - 1; if r<>0 then PC ← PC - d 4 7 7 JSR 0 0 1 1 0 x r r r x x m m m r r r temp ← endereço de desvio (modo 0 = NOP) pilha ← registrador r registrador r ← PC PC ← temp 7 0 0 RTS 1 1 1 x r r r PC ← registrador r registrador r ← pilha 0 1 0 0 0 c c c c x x m m m r r r cccc instrução significado 0000 CLR op ← 0 0001 NOT op ← NOT op 0010 INC op ← op + 1 0011 DEC op ← op - 1 0100 NEG op ← - op 0101 TST op ← op 0110 ROR op ← SHR(c & op) 0111 ROL op ← SHL(op & c) 1000 ASR op ← SHR(msb & op) 1001 ASL op ← SHL(op & 0) 1010 ADC op ← op + c 1011 SBC op ← op - c N Z C V t t 0 0 t t 1 0 t t t t t t not(t) t t t not(t) t t t 0 0 t t lsb xor t t msb xor t t lsb xor t t msb xor t t t t t t t t Obs: após uma subtração, C = 1 indica BORROW ! Exemplos de somas - codificar 7 0 1 c c c m m m r r r m m m r r r ccc instrução significado 001 MOV dst ← src 010 ADD dst ← dst + src 011 SUB dst ← dst - src 100 CMP src - dst 101 AND dst ← dst AND src 110 OR dst ← dst OR src N t t t t t t Z t t t t t t V C 0 t t t not(t) t not(t) 0 0 - Primeiro operando = origem Segundo operando = destino Obs: após uma subtração, C = 1 indica BORROW ! Exemplos de somas - codificar • R1 = R1 + Topo da pilha, sem retirar da pilha ADD (R6),R1 • R1 = R1 + Topo da pilha, retirando da pilha ADD (R6)+,R1 • Somar as duas palavras do topo da pilha, e devolver o resultado para o topo da pilha ADD (R6)+,(R6) • R1 = R1 +R2 ADD R2,R1 • R1 = R1 + MEM(2000) ADD 2000,R1 • MEM(3000) = MEM(3000) + r2 ADD R2,3000 • MEM(3000) = MEM(3000) + MEM(2000) ADD 2000,3000 • R1 = R1 + 5 ADD #5,R1 • MEM(1300) = MEM(1300) + 300 ADD #300,1300 Entrada e Saída • visor alfanumérico de 36 posições, que permite visualizar letras (maiúsculas e minúsculas), dígitos (0 a 9) e caracteres especiais do conjunto ASCII padrão americano (códigos ASCII 0 a 127). • teclado que permite ler um caractere (ASCII) e testar se uma tecla foi pressionada. 5 Entrada e Saída • E/S mapeada na memória. • os últimos 38 endereços de memória (65498 a 65535) são mapeados para os dois periféricos. • transferências para esta área são sempre de 1 byte - somente os 8 bits menos significativos do operando são transferidos. Teclado • A interface com o teclado é mapeada para dois bytes da memória Visor • Mapeado para os endereços 65500 a 65535 da memória • Somente caracteres representáveis do conjunto ASCII padrão americano são visíveis (3210 ≤ código ASCII ≤ 12610 - ver Tabela 8.12) • Todos os demais caracteres são mostrados como um espaço em branco Uso do teclado • Esperar até que o endereço 65498 contenha 128 • Ler do endereço 65499 o código ASCII digitado • O byte 65499 contém o último caractere digitado (“buffer”) • Após, o endereço 65498 deve ser zerado • O byte 65498 indica o estado do teclado • Isto indica que outro caractere pode ser recebido do teclado – Valor 128 (80H) : foi digitado um caractere – Valor 0: nenhuma tecla foi pressionada Exemplo de E/S • Rotina para ler um caractere CLR 65498 TST 65498 BEQ -6 ; (250) • Alternativa mais eficiente - para digitadores profissionais ;-) MOV #65498, R3 CLR (R3) TST (R3) BEQ -4 • Enquanto o endereço 65498 não for zerado, todas as teclas pressionadas são ignoradas Exemplo de E/S • Leitura de caractere com eco (exibição no visor) MOV #65498, R3 CLR (R3) TST (R3) BEQ -4 ; (252) MOV 65499, 65500 BR -14 ; (242) 6 Exemplo de E/S Exemplo de E/S • Leitura de caractere com eco e fila (exibição em posições consecutivas do visor) MOV #65498, R3 MOV #65500, R1 CLR (R3) TST (R3) BEQ -4 MOV 65499, (R1) INC R1 BR -14 CLR (R3) TST (R3) BEQ -4 ; (252) ; (252) MOV 65499, (R1) INC R1 ; (242) • Três parâmetros, por valor 1000 MOV (R5)+,R1 1002 MOV (R5)+,R2 1004 MOV (R5)+,R3 1006 …. ….. 1100 RTS R5 Subrotina - caso 3 • Dois parâmetros e um resultado 100 JSR R5, 1000 104 param1 106 param2 108 end.resultado 110 <próx.instr.> MOV #65498, R3 MOV #65500, R1 Subrotina - caso 1 100 JSR R5, 1000 104 param1 106 param2 108 param3 110 <próx.instr.> • Resolvendo o problema de “estouro” do visor 1000 MOV (R5)+,R1 1002 MOV (R5)+,R2 1004 MOV (R5)+,R4 1006 …. ….. 1096 MOV resul,(R4) 1100 RTS R5 BEQ -18 ; (238) BR -16 ; (240) Subrotina - caso 2 • Três parâmetros, último por nome (endereço) 100 JSR R5, 1000 104 param1 106 param2 108 end.param3 110 <próx.instr.> 1000 MOV (R5)+,R1 1002 MOV (R5)+,R2 1004 MOV ((R5)+),R3 1006 …. ….. 1100 RTS R5 Subrotina - parâmetros na pilha • Três parâmetros 100 MOV param1, -(R6) 102 MOV param2, -(R6) 104 MOV param3, -(R6) 106 JSR R7, 1000 110 <próx.instr.> • Como obter os parâmetros e deixar a pilha em ordem ? 7 Subrotina - parâmetros na pilha • Como deixar a pilha em ordem ? • Não mexer na pilha ! Subrotina - parâmetros na pilha • Como obter os parâmetros ? • Modo indexado ! 100 MOV param1, -(R6) 102 MOV param2, -(R6) 104 MOV param3, -(R6) 106 JSR R7, 1000 110 ADD #6, R6 ; 6 bytes = 3 parâmetros 114 <próx.instr.> 100 MOV param1, -(R6) 102 MOV param2, -(R6) 104 MOV param3, -(R6) 106 JSR R7, 1000 110 ADD #6, R6 114 <próx.instr.> Subrotina - parâmetros na pilha • Como obter os parâmetros ? 100 MOV R6,R5 102 MOV param1, -(R6) 104 MOV param2, -(R6) 106 MOV param3, -(R6) 108 JSR R7, 1000 112 ADD #6, R6 116 <próx.instr.> Endereço 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 128 129 130 131 132 133 134 Instrução LDA 132 STA 130 LDA 129 STA 17 LDA 128 STA 131 JZ 34 LDA 130 ADD 17 STA 130 LDA 17 ADD 134 STA 17 LDA 131 ADD 133 STA 131 JMP 12 HLT n e tot cont 0 255 1 1000 MOV -2(R5),R1 1002 MOV -4(R5),R2 1004 MOV -6(R5),R3 1006 …. ….. 1100 RTS R7 1000 MOV 6(R6),R1 1002 MOV 4(R6),R2 1004 MOV 2(R6),R3 1006 …. ….. 1100 RTS R7 Programa Exemplo Somar (totalizar) n posições consecutivas de memória, a partir do endereço inicial e. (Sem consistência sobre os valores de n e e). Em alto nível, o programa seria: total:=0 ponteiro := e contador := n laço: if contador = 0, termina total := total + mem(ponteiro) ponteiro := ponteiro + 1 contador := contador – 1 goto laço ; inicializa (zera) o total ; inicializa ponteiro Implementação Ramses ; inicializa contador Endereço 0 2 4 6 8 10 12 14 16 18 128 129 130 ; testa se contador é zero ; carrega total no acumulador ; soma com posição de memória ; atualiza total ; incrementa ponteiro ; decrementa contador ; retorna ao início do laço número de posições endereço inicial total contador constante zero constante -1 constante 1 Instrução LDR A #0 LDR X 129 LDR B 128 JZ 16 ADD A 0,X ADD X #1 SUB B #1 JMP 6 STR A 130 HLT n e total ; inicializa (zera) o total ; inicializa ponteiro ; inicializa contador ; testa se contador é zero ; soma com posição de memória ; incrementa ponteiro ; decrementa contador ; retorna ao início do laço ; atualiza total número de posições endereço inicial Neander 8 Implementação Cesar • Tradução literal de cada instrução Endereço 0 4 8 12 14 16 20 24 28 32 1024 1026 1028 Instrução MOV #0, R0 MOV 1026, R2 MOV 1024, R1 BEQ +14 ADD (R2), R0 ADD #2, R2 SUB #1, R1 JMP 12 MOV R0, 1028 HLT n e total ; inicializa (zera) o total ; inicializa ponteiro ; inicializa contador ; testa se contador é zero ; soma com posição de memória ; incrementa ponteiro ; decrementa contador ; retorna ao início do laço ; atualiza total número de posições endereço inicial Implementação Cesar • Usando instruções específicas do Cesar Endereço 0 2 6 10 12 14 18 20 22 26 1024 1026 1028 Implementação Cesar • Usando endereçamento pós incrementado Endereço 0 2 6 10 12 14 16 18 22 1024 1026 1028 Instrução CLR R0 MOV 1026, R2 MOV 1024, R1 BEQ +6 ADD (R2)+, R0 DEC R1 BR -14 MOV R0, 1028 HLT n e total ; inicializa (zera) o total ; inicializa ponteiro ; inicializa contador ; testa se contador é zero ; soma com posição de memória ; e incrementa ponteiro ; decrementa contador ; retorna ao início do laço ; atualiza total número de posições endereço inicial Instrução CLR R0 MOV 1026, R2 MOV 1024, R1 BEQ +10 ADD (R2), R0 ADD #2, R2 DEC R1 BR -14 MOV R0, 1028 HLT n e total ; inicializa (zera) o total ; inicializa ponteiro ; inicializa contador ; testa se contador é zero ; soma com posição de memória ; incrementa ponteiro ; decrementa contador ; retorna ao início do laço ; atualiza total número de posições endereço inicial Implementação Cesar • Usando instrução SOB Endereço 0 2 6 10 12 Instrução CLR R0 MOV 1026, R2 MOV 1024, R1 BEQ +4 ADD (R2)+, R0 14 SOB R1, 4 16 20 1024 1026 1028 MOV R0, 1028 HLT n e total ; inicializa (zera) o total ; inicializa ponteiro ; inicializa contador ; testa se contador é zero ; soma com posição de memória ; e incrementa ponteiro ; decrementa contador ; retorna ao início do laço ; atualiza total número de posições endereço inicial carga REM Soma de variáveis de 32 bits MOV 1026, R0 ADD 1030, R0 MOV R0, 1034 MOV #0, R0 ADC R0 ADD 1024, R0 ADD 1028, R0 MOV R0, 1032 HLT ; Bits menos significativos da primeira variável ; Soma com bits menos significativos da segunda variável ; Salva resultado da soma (nos bits menos significativos ) ; Zera o registrador R0 (prepara para receber o carry) ; Soma o carry da soma anterior ; Soma com bits mais significativos da primeira variável ; Soma com bits mais significativos da segunda variável ; Salva o resultado (bits mais significativos) R E M read MEM write RDM carga RDM write reg Reg. Gerais e Temporário read reg sel reg s1 Raux carga Raux carga RI Y X RI carry in UAL DECOD. V N C Z carga liga desliga VNCZ Unidade de Controle Sinais de Controle para a UCP 9 • Movimento de blocos de n posições: faça um programa para mover (sem zerar a origem) um número qualquer de posições consecutivas na memória. O número de posições é determinado pelo conteúdo da posição 1024 de memória, a posição inicial do bloco de memória a ser movido é dada pelo conteúdo da posição 1026 de memória e o endereço inicial do bloco de destino é dado pela posição 1028. – posição 1024: número de posições – posição 1026: posição inicial da origem – posição 1028: posição inicial do destino Pesquisa em vetores: faça um programa para determinar o maior valor armazenado em um vetor (array). O tamanho do vetor é determinado pelo conteúdo da posição 1024 de memória e a posição inicial do vetor é dada pelo conteúdo da posição 1026. O maior valor encontrado deve ser colocado na posição 1028, e a posição relativa desse valor no vetor (1º, 2º, ..., n-ésimo) na posição 1030. – – – – posição 1024: número de posições (tamanho do vetor) posição 1026: posição inicial do vetor posição 1028: resultado: maior valor encontrado posição 1030: resultado: posição relativa do maior valor • Alteração de bits: escreva um programa que zere (clear) ou ligue (set) um bit qualquer de uma palavra qualquer da memória, conforme indicado por um parâmetro na memória. – posição 1024: – posição 1026: – posição 1028: endereço da palavra a ser alterada posição do bit a ser alterado (0 é o lsb) conteúdo = 0, para zerar conteúdo = 1, para ligar MOV 1024, R0 MOV 1026, R1 MOV 1028, R2 CMP R2, R1 BGT 5 MOV (R1)+, (R2)+ SOB R0, 4 HLT ASL R0 ADD R0, R1 ADD R0, R2 MOV 1024, R0 MOV -(R1), -(R2) SOB R0, 4 HLT ; Tamanho do bloco (em palavras) ; Endereço inicial da origem ; Endereço inicial do destino ; Compara endereço de destino com o de origem ; Desvia de end.destino > end.origem ; Move uma palavra no sentido crescente ; Laço para mover toda a área ; Fim do programa ; Multiplica tamanho por dois (obtém tamanho em bytes) ; Endereço final da origem (+ 2 bytes) ; Endereço final do destino (+ 2 bytes) ; Restaura tamanho para palavras ; Move uma palavra, no sentido decrescente ; Laço para mover toda a área MOV 1024, R0 MOV 1026, R1 MOV (R1)+, R2 MOV R0, R3 DEC R0 CMP (R1), R2 BLE 4 MOV (R1), R2 MOV R0, R3 ADD #2, R1 SOB R0, 14 MOV R2, 1028 MOV 1024, R4 SUB R3, R4 INC R4 ; MOV R4, 1030 HLT ; Tamanho do vetor (em palavras) ; Endereço inicial do vetor ; Inicializa o primeiro elemento como sendo o maior ; Inicializa R3 com o índice (“tamanho”) do maior elemento ; Inicializa contador (tamanho – 1) ; Compara um elemento com o maior atual ; Desvia se for menor ou igual ; Se for maior, atualiza R2 ; Salva índice do novo maior valor (“contador atual”) ; Em qualquer caso, incrementa ponteiro ; Controle do laço ; Fornece maior valor encontrado ; Calcula índice do maior valor ; índice = tamanho – contador + 1 índice = mem(1024) – R3 + 1 ; Fornece o índice do maior valor MOV 1026, R1 JSR R7, 100 TST 1028 BEQ 6 OR R0, 1024 BR 6 NOT R0 AND R0, 1024 HLT ; Obtém índice do bit a ser alterado ; Chama a subrotina de geração da máscara ; Testa se o bit deve ser ligado ou desligado ; Deve ser desligado ; Deve ser ligado, usar OR ; Vai para o fim do programa ; Desligar bit: inverte a máscara ; Desliga o bit usando AND No endereço 100: MOV #1, R0 ; R0 contém a máscara (inicializada com 0000000000000001) TST R1 ; R1 contém o índice do bit a ser isolado (0 é o bit menos sign.) BEQ 4 ; Se o índice é zero, a máscara está pronta ASL R0 ; Desloca o bit da máscara para esquerda SOB R1, 4 ; Decrementa o índice e desloca a máscara até o índice ser zero RTS R7 ; Retorna ao programa principal (máscara em R0) 10