Universidade Lusfona Informtica de Gesto Trabalho realizado por Filipe Custdio Guilherme Portalegre Paulo Fernandes Erivaldo Silva
Universidade Lusfona de Lisboa
Arquitectura de Computadores
Licenciatura em Informtica de Gesto, Turma 1N1
Professores: Alexandre Pereira, Pedro Freire
Arquitectura de Computadores
Fevereiro 2010
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
Trabalho Prtico de
Arquitectura de Computadores
Introduo
Foi-nos pedido, no mbito da disciplina de Arquitectura de Computadores, que realizssemos um projecto como objecto de avaliao
final da mesma.
Esse projecto, desenvolvido em linguagem Assembly efecuta as quatro operaes bsicas de somar, subtrair, multiplicar e dividir.
Estas operaes so realizadas sobre nmeros representados na forma hexadecimal e o resultado mostrado tambm em formato
hexadecimal. Tambm realiza estas quatro operaes sobre numeros de virgula flutuante na forma IEEE-754, em formato curto ou
longo.
Disponiliza tambm as operaes lgicas de OR, AND, XOR e as de deslocamento RIGHT SHIFT, LEFT SHIFT, ROLL RIGHT e
ROLL LEFT. Estas operaes s esto disponiveis para operandos inteiros.
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
Ferramentas Utilizadas
O programa foi desenvolvido em Assembler, para linux, e compilado com NASM.
Foram utilizadas as ferramentas RadAsm e GNU Debugger para desenvolver e analisar o programa.
O RadAsm permitiu desenvolver num ambiente IDE com sintaxe colorida e permitindo compilar utilizando o NASM para windows.
Embora o programa no funcione em windows esta forma de trabalhar permite indentificar e corrigir erros de sintaxe no cdigo de
uma forma muito rpida. Em contrapartida requere que o cdigo fonte seja copiado para o linux e ser posteriormente compilado.
O GNU Debugger permitiu identificar erros semnticos. Quando se compila com o NASM e se usa a flag g so colocadas no cdigo
informaes que permitem posteriormente em tempo de execuo parar o cdigo para analisar endereos de memria e registos. Os
comandos mais utililizados foram: r para iniciar o programa; step para executar instruo a instruo; p/a var@count para
mostrar o conteudo de variaveis; info register para ver os registos; info float para ver o stack de virgula flutuante. Desta forma foi
possivel perceber e corrigir alguns erros relacionados com os formatos IEEE-754 e little endian do processador Intel.
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
Arquitectura
O programa baseado no programa de calculadora desenvolvido durante as aulas prticas e a sua estrutura pode ser divida em duas
partes: a parte inicial em que recebe os operandos e o operador e a parte final em que realiza a operao.
A parte inicial tem o seguinte fluxograma:
Inicio
Input Formato
Input operando 1
Input operando 2
Input Operador
Formato vlido?
No
Sim
Soma? SomaSim
Converte operando 1
Converte operando 2
Subtrao?
No
SubtraoSim
Multiplicao?
No
MultiplicaoSim
Diviso?
No
DivisoSim
Inteiro ?
No
Erro OperadorNo
OR ?
Sim
OrSim
AND ?
No
XOR ?
No
SL ?
No
SR ?
No
RR
No
AndSim
XorSim
Shift LeftSim
Shift RightSim
Roll RightSim
Escreve resultado
RL
No
No Roll LeftSim
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
As operaes por sua vez podem der divididas em dois tipos diferentes de operaes: operaes que admitem numeros reais e
operaes apenas de inteiros. Cada conjunto de operaes tm fluxogramas idnticos.
As operaes que admitem numeros reais so a soma, subtrao, multiplicao e diviso e tm o seguinte fluxo:
Operaes com Reais ou Inteiros
Inteiros?
Operaocom
inteiros
Real curto ?
Operao com reais curtos
Overflow ?
Operao com reais longos
Overflow
Sim
Escreve Resultado
No
As operaes apenas com nmeros inteiros (operaes lgicas e de deslocamento) tm o seguinte fluxograma:
Operaes com Inteiros
Executar operao
Overflow ?
Escrever resultado
No
Erro overflowSim
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
Cdigo:
; baseado no "calc2.asm" do prof Alexandre Pereira
MAX_BUFFER equ 80+2
section .data
str_pede_fmt db "Introduza o formato - (i)nteiros, reais (c)urtos, reais (l)ongos: "
tam_pede_fmt equ $ - str_pede_fmt
str_pede_op1 db "Introduza o primeiro operando: "
tam_pede_op1 equ $ - str_pede_op1
str_pede_op2 db "Introduza o segundo operando: "
tam_pede_op2 equ $ - str_pede_op2
str_resultado db "Resultado: "
tam_resultado equ $ - str_resultado
str_op db "Introduza o operador (+,-,*,/,&,|,^,SL,SR,RL,RR}: "
tam_op equ $ - str_op
str_erro_overflow db "Resultado demasiado grande!", 0xA
tam_erro_overflow equ $ - str_erro_overflow
str_erro_operador db "Operador invalido!", 0xA
tam_erro_operador equ $ - str_erro_operador
str_eol db 0xA
tam_eol equ $ - str_eol
formato db 0
num1 dd 0, 0
num2 dd 0, 0
operador dw 0
resultado dd 0, 0
tam_buffer dd 0
section .bss
buffer resb MAX_BUFFER
section .text
global _start
_start:
mov eax, ds
mov es, eax
; BLOCO 1
; Pede o formato dos operandos
pede_formato:
mov edx, tam_pede_fmt
mov ecx, str_pede_fmt
mov ebx, 1
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
mov eax, 4
int 0x80
; le^ formato
mov edx, 2
mov ecx, buffer
mov ebx, 0
mov eax, 3
int 0x80
mov bx, [buffer]
cmp bl, 'i'
je formato_valido
cmp bl, 'c'
je formato_valido
cmp bl, 'l'
jne pede_formato
formato_valido:
mov [formato], bl
; Pede os operandos e o operador
; pede, le^ e converte num1
; mostra prompt no ecra
mov eax, tam_pede_op1
mov ebx, str_pede_op1
call pede_num
mov [num1], eax
mov [num1+4], edx
; pede, le^ e converte num2
mov eax, tam_pede_op2
mov ebx, str_pede_op2
call pede_num
add esp, 8
mov [num2], eax
mov [num2+4], edx
; pede operador
mov edx, tam_op
mov ecx, str_op
mov ebx, 1
mov eax, 4
int 0x80
; le^ operador
mov edx, MAX_BUFFER
mov ecx, buffer
mov ebx, 0
mov eax, 3
int 0x80
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
; BLOCO 2
; Executa a operacao
mov bx, [buffer] ; le^ o caracter do "operador"
cmp bl, '+'
je soma
cmp bl, '-'
je subtrai
cmp bl, '*'
je multiplica
cmp bl, '/'
je divide
cmp byte[formato], 'i'
jne erro_operador
cmp bl, '|'
je bitwise_or
cmp bl, '&'
je bitwise_and
cmp bl, '^'
je bitwise_xor
cmp bx, 'SL'
je shift_left
cmp bx, 'SR'
je shift_right
cmp bx, 'RL'
je roll_left
cmp bx, 'RR'
je roll_right
; se nao for nenhum operador, o "resultado" e' zero
operador_invalido:
xor eax, eax
xor edx, edx
jmp escreve
soma:
cmp byte[formato], 'i'
jne soma_reais
mov eax, [num1]
add eax, [num2]
jc erro_overflow
mov [resultado], eax
jmp escreve
soma_reais:
cmp byte[formato], 'c'
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
je soma_reais_curtos
fld qword[num2]
fadd qword[num1]
fstp qword[resultado]
jo erro_overflow
jmp escreve
soma_reais_curtos:
fld dword[num2]
fadd dword[num1]
fst dword[resultado]
jo erro_overflow
jmp escreve
subtrai:
cmp byte[formato], 'i'
jne subtrai_reais
mov ebx, [num1]
sub ebx, [num2]
jo erro_overflow
mov [resultado], ebx
jmp escreve
subtrai_reais:
cmp byte[formato], 'c'
je subtrai_reais_curtos
fld qword[num2]
fsub qword[num1]
fstp qword[resultado]
jo erro_overflow
jmp escreve
subtrai_reais_curtos:
fld dword[num2]
fsub dword[num1]
fst dword[resultado]
jo erro_overflow
jmp escreve
multiplica:
cmp byte[formato], 'i'
jne multiplica_reais
mov eax, [num2]
mul dword[num1]
jc erro_overflow
mov [resultado], eax
jmp escreve
multiplica_reais:
cmp byte[formato], 'c'
je multiplica_reais_curtos
fld qword[num2]
fmul qword[num1]
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
fstp qword[resultado]
jo erro_overflow
jmp escreve
multiplica_reais_curtos:
fld dword[num2]
fmul dword[num1]
fst dword[resultado]
jo erro_overflow
jmp escreve
divide:
cmp byte[formato], 'i'
jne divide_reais
xor edx, edx
mov eax, [num1]
mov ebx, [num2]
cmp ebx, 0
je erro_overflow
div ebx
mov [resultado], eax
jmp escreve
divide_reais:
cmp byte[formato], 'c'
je divide_reais_curtos
fld qword[num2]
fdiv qword[num1]
fstp qword[resultado]
jo erro_overflow
jmp escreve
divide_reais_curtos:
fld dword[num2]
fdiv dword[num1]
fst dword[resultado]
jo erro_overflow
jmp escreve
shift_left:
; esta operacao faz num2 RightShift sobre num1
mov ecx, [num2]
mov eax, [num1]
cmp ch, 0
jne erro_overflow
shl eax, cl
jo erro_overflow
mov [resultado], eax
jmp escreve
shift_right:
; esta operacao faz num2 LeftShift sobre num1
mov ecx, [num2]
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
mov eax, [num1]
cmp ch, 0
jne erro_overflow
shr eax, cl
jo erro_overflow
mov [resultado], eax
jmp escreve
roll_left:
; esta operacao faz num2 RollRigth sobre num1
mov ecx, [num2]
mov eax, [num1]
cmp ch, 0
jne erro_overflow
rol eax, cl
jo erro_overflow
mov [resultado], eax
jmp escreve
roll_right:
; esta operacao faz num2 RollLeft sobre num1
mov ecx, [num2]
mov eax, [num1]
cmp ch, 0
jne erro_overflow
ror eax, cl
jo erro_overflow
mov [resultado], eax
jmp escreve
bitwise_or:
mov ebx, [num2]
mov eax, [num1]
or eax, ebx
jo erro_overflow
mov [resultado], eax
jmp escreve
bitwise_and:
mov ebx, [num2]
mov eax, [num1]
and eax, ebx
jo erro_overflow
mov [resultado], eax
jmp escreve
bitwise_xor:
mov ebx, [num2]
mov eax, [num1]
xor eax, ebx
jo erro_overflow
mov [resultado], eax
jmp escreve
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
; BLOCO 3
; Escreve o resultado no ecra
escreve:
; exibe str_resultado
mov edx, tam_resultado
mov ecx, str_resultado
mov ebx, 1
mov eax, 4
int 0x80
; converte parte baixa
mov eax, [resultado+4]
call conv_num
; exibe o resultado
mov edx, 8
mov ecx, buffer
mov ebx, 1
mov eax, 4
int 0x80
; converte parte alta
mov eax, [resultado]
call conv_num
; exibe o resultado
mov edx, 8
mov ecx, buffer
mov ebx, 1
mov eax, 4
int 0x80
; exibe str_eol (quebra de linha)
call muda_linha
; sair do programa
mov ebx, 0
mov eax, 1
int 0x80
; BLOCO 4
;============================================================================
;#### Funcao "muda_linha" ###################################################
;============================================================================
; nao tem argumentos
muda_linha:
mov edx, tam_eol
mov ecx, str_eol
mov ebx, 1
mov eax, 4
int 0x80
ret
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
;============================================================================
;#### Funcao "pede_num" ###################################################
;============================================================================
; Recebe dois argumentos e devolve em eax o numero lido
; eax: tamanho str
; ebx: str
pede_num:
mov edx, eax
mov ecx, ebx
mov ebx, 1
mov eax, 4
int 0x80
; le^ o numero escrito pelo utilizador para "buffer"
mov edx, MAX_BUFFER
mov ecx, buffer
mov ebx, 0
mov eax, 3
int 0x80
dec eax
mov [tam_buffer],eax
; converte o numero em "buffer" de string em hexadecimal
; para numero inteiro
xor eax, eax
xor ebx, ebx
xor edx, edx
mov esi, buffer
cld
mov ecx, [tam_buffer]
jecxz pede_num_fim
pede_num_conv:
lodsb
cmp al, '9'
jbe pede_num_digito
add al, 9
pede_num_digito:
and al, 0xF
shl ebx, 1
rcl edx, 1
shl ebx, 1
rcl edx, 1
shl ebx, 1
rcl edx, 1
shl ebx, 1
rcl edx, 1
add ebx, eax
loop pede_num_conv
pede_num_fim:
; copia o resultado para eax e retorna
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
mov eax, ebx
ret
conv_num:
; transforma "resultado" em string
mov ecx, 8 ; 4 bytes em [resultado] => 8 digitos hexadecimais
mov edi, buffer
mov ebx, eax
cld
xor eax, eax
escreve_conv:
rol ebx, 4
mov eax, ebx
and eax, 0xF
cmp eax, 0x9
jbe escreve_digito
add al, 'A'-0xA
jmp escreve_prox
escreve_digito:
add al, '0'
escreve_prox:
stosb
loop escreve_conv
ret
erro_overflow:
mov edx, tam_erro_overflow
mov ecx, str_erro_overflow
mov ebx, 1
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
erro_operador:
mov edx, tam_erro_operador
mov ecx, str_erro_operador
mov ebx, 1
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
Bibliografia e Referncias
Brewer, Kevin J. IEEE-754 Floating-Point Conversion. Dr. Christopher Vickerys Web Site. [Online] http://babbage.cs.qc.cuny.edu/IEEE-754/64bit.html.
Free Software Foundation, Inc. Debugging with gdb. sourceware.org. [Online] Free Software
Foundation, Inc. http://sourceware.org/gdb/current/onlinedocs/gdb/index.html#Top.
Freire, Pedro. Ensino. [Online] http://www.pedrofreire.com/tutor_pt.htm.
Hyde, Randall. The Art of Assembly - 14.4.3 The FPU Instruction Set. The Webster. [Online]
http://webster.cs.ucr.edu/AoA/DOS/ch14/CH14-4.html#HEADING4-68.
. The Art of Assembly Language. Ippolito, Greg. GNU GDB Debugger Command Cheat Sheet. [Online]
http://www.yolinux.com/TUTORIALS/GDB-Commands.html.
Pereira, Alexandre. Arquitectura de Computadores. [Online] http://escola.mediateca.pt/ac/.
Smit, Ferdi. Assembly Tutorial. [Online] http://www.xs4all.nl/~smit/asm01001.htm.
Universidade Lusfona de Lisboa
Trabalho prtico de Arquitectura de Computadores
Trabalho realizado por:
Filipe Custdio (a20090639)
Guilherme Portalegre (a20091469)
Paulo Fernandes (a20093093)
Erivaldo Silva (a20095851)
Top Related