NEANDERWIN - Resumo operacional

Documentos relacionados
NEANDERWIN. Algumas características do processador Neander são:

Linguagem de Montagem do NeanderX

ção de Computadores I

SimuS. Gabriel P. Silva. José Antonio Borges. Um Simulador Didático para o Ensino de Arquitetura de Computadores DCC-IM/UFRJ NCE/UFRJ

Neander - características

A Arquitetura: conjunto de instruções

Esta pseudomáquina foi criada em homenagem ao homem de Neandertal, o antecessor do homo sapiens.

FORMATO DO PROGRAMA FONTE

Aula 14 Funcionamento de Processadores (Visão específica)

O Computador Neander Neander - Computador Hipotético Didático

Disciplina de Organização de Computadores I

ORGANIZAÇÃO DE COMPUTADORES

Computador Cleópatra

Arquitetura de Computadores Conceitos Fundamentais. Graduação em Engenharia Elétrica - UFPR Prof. Carlos Marcelo Pedroso 2016

Instruções de Máquina

Arquitetura: características gerais

9. Software de Sistema - Montadores (capítulo 9 do livro texto)

Microprocessadores I ELE Aula 7 Conjunto de Instruções do Microprocessador 8085 Desvios

Porque usar um montador? Formato de uma linha de código fonte:

Microcontroladores. Conjunto de Instruções do Prof. Guilherme Peron Prof. Heitor Lopes Prof. Ronnier Rohrich Prof. Rubão

ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES A UNIDADE LÓGICA ARITMÉTICA E AS INSTRUÇÕES EM LINGUAGEM DE MÁQUINA

ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES A UNIDADE LÓGICA ARITMÉTICA E AS INSTRUÇÕES EM LINGUAGEM DE MÁQUINA

Solução Lista de Exercícios Processadores

Prof. Leonardo Augusto Casillo

Organização e Projeto de Computadores 3: Modo de Endereçamento, Sub-Rotina, Instruções de E/S, Interrupção

Sistemas de Computação. Instruções de Linguagem de Máquina

Prof. Adilson Gonzaga

Utilização do montador Daedalus. O montador e os simuladores Formatos de instruções

Arquitetura e Organização de Computadores

Arquitetura e Organização de Computadores

SimuS Um Simulador Para o Ensino de Arquitetura de Computadores

MATA49 Programação de Software Básico

Linguagem de Maquina II. Visão Geral

William Stallings Arquitetura e Organização de Computadores 8 a Edição

PARTE II - CONJUNTO DE INSTRUÇÕES ARQUITETURA DE COMPUTADORES ANTONIO RAMOS DE CARVALHO JÚNIOR

Organização e Arquitetura de Computadores I

Computador Cleópatra

Conjunto de instruções e modos de. aula 4. Profa. Débora Matos

Conjunto de Instruções e Modelos de Arquiteturas

Projetando um Computador

Estruturas da linguagem C. 1. Identificadores, tipos primitivos, variáveis e constantes, operadores e expressões.

Conjunto de Instruções e Modelos de Arquiteturas

Projetando um Computador Parte II Arquitetura do Processador BIP

As 5 partes fundamentais. Linguagem de Programação Pinagem Características Elétricas Ambiente de Desenvolvimento Integrado - IDE

Programação de Microprocessadores. Programação de Microprocessadores SEL-433 APLICAÇÕES DE MICROPROCESSADORES I

Instruções. Maicon A. Sartin

7. PROGRAMANDO O MICROCONTROLADOR. Microcontroladores - Prof: Demantova

LISTA 02 CONJUNTO DE INSTRUÇÕES - GABARITO

Tópicos: 1 - Modos de endereçamento do Pilha e instruções de Pilha. 3 - Instruções que usam pilha: - instrução CALL - instrução RET

Microcontrolador Assembly UTFPR / DAELN Microcontroladores 1 Prof. Gabriel Kovalhuk

COMPUTADOR 2. Professor Adão de Melo Neto

III.2 - Princípios de Arquitetura

Sistemas Processadores e Periféricos Aula 2 - Revisão

Sistemas de Computação

Capítulo 2 Operadores. A função scanf()

Aula 10 Microcontrolador Intel 8051 Parte 2

Sistemas de Computação para Controle e Automação CIC132. Assembly. Assembly. Notas. Décima quarta aula: Introdução a programação Assembly

Prof. Leonardo Augusto Casillo

Figura 1. Datapath do MIPS Superescalar Especulativo CES SE

José Augusto Fabri. Assembly Básico

UCP 8051 (parte 02) Professor Adão de Melo Neto

Sistemas Operacionais

EXERCÍCIOS RESOLVIDOS

Exercícios Suplementares de Programação Assembly da Cleópatra

SIMULAÇÃO DE MÁQUINA DE REGISTRADORES COM MÁQUINA DE TURING MULTIFITA

Endereçamento e Formato de Instruções

2.4 Processadores Micro-instruções Desvios Desvios Condicionais Instruções e Programação em Assembler

SSC0611 Arquitetura de Computadores

CONJUNTO DE INSTRUÇÕES

7. A pilha e subrotinas

Sistemas Microprocessados. sato<at>utfpr<dot>edu<dot>br

Cesar - características CESAR. Registradores. Modos de endereçamento. Endereçamento de memória. Modo Registrador. (As bases da civilização atual)

Funcionamento básico de um computador

Introdução à Arquitetura de Computadores

EEL Microprocessadores

MICROPROCESSADORES E MICROCONTROLADORES PROVA 1

Microprocessadores I. Aula 6 Arquitetura do Microprocessador Pinagem e Diagrama de Temporização

Instruções Assembly x Código de máquina Microprocessador Didático

Organização e Projeto de Computadores

Laboratório de Microprocessadores e Microcontroladores

SSC510 Arquitetura de Computadores 1ª AULA

Laboratório de Microprocessadores e Microcontroladores

Arquitetura de Computadores. Ciclo de Busca e Execução

Transcrição:

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