Você está na página 1de 16

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

Informtica de Gesto

Trabalho realizado por

Filipe Custdio Guilherme Portalegre

Paulo Fernandes Erivaldo Silva

Universidade Lusfona de Lisboa

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.

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

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.

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

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:

Soma?

Inicio

Sim

Soma

Sim

Subtrao

Sim

Multiplicao

Sim

Diviso

No

Erro Operador

Sim

Or

Sim

And

Sim

Xor

Sim

Shift Left

Sim

Shift Right

Sim

Roll Right

Sim

Roll Left

No
Input
Formato

Subtrao?
No

No

Formato vlido?

Multiplicao?

Sim

No

Input
operando 1

Diviso?

No

Input
operando 2

Inteiro ?

Sim

Input
Operador

OR ?

No

Converte
operando 1

AND ?

No

Converte
operando 2

XOR ?

No

SL ?

No

SR ?

No

RR

No

Escreve
resultado

No

RL

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

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?

Real curto ?

Operao
com
inteiros

Operao com reais


curtos

No

Overflow ?

Escreve
Resultado

Operao
com reais longos

Sim

Overflow

As operaes apenas com nmeros inteiros (operaes lgicas e de deslocamento) tm o seguinte fluxograma:
Operaes com
Inteiros

Executar operao

Overflow ?

Sim

Erro overflow

No

Escrever
resultado

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

Cdigo:

; baseado no "calc2.asm" do prof Alexandre Pereira


MAX_BUFFER

equ

80+2

str_pede_fmt
tam_pede_fmt

db
equ

"Introduza o formato - (i)nteiros, reais (c)urtos, reais (l)ongos: "


$ - str_pede_fmt

str_pede_op1
tam_pede_op1

db
"Introduza o primeiro operando: "
equ $ - str_pede_op1

str_pede_op2
tam_pede_op2

db
"Introduza o segundo operando: "
equ $ - str_pede_op2

str_resultado
tam_resultado

db
equ

section .data

"Resultado: "
$ - str_resultado

str_op
tam_op

db
equ

"Introduza o operador (+,-,*,/,&,|,^,SL,SR,RL,RR}: "


$ - str_op

str_erro_overflow db
tam_erro_overflow equ

"Resultado demasiado grande!", 0xA


$ - str_erro_overflow

str_erro_operador db
tam_erro_operador equ

"Operador invalido!", 0xA


$ - str_erro_operador

str_eol
tam_eol

db
equ

0xA
$ - str_eol

formato
num1
num2
operador dw
resultado dd

db
dd
dd
0
0, 0

0
0, 0
0, 0

tam_buffer

dd

resb

MAX_BUFFER

section .bss
buffer
section .text
global _start
_start:
mov
mov

eax, ds
es, eax

; BLOCO 1
; Pede o formato dos operandos
pede_formato:
mov
mov
mov

edx, tam_pede_fmt
ecx, str_pede_fmt
ebx, 1

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

mov
int

eax, 4
0x80

; le^ formato
mov
mov
mov
mov
int

edx, 2
ecx, buffer
ebx, 0
eax, 3
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
mov
mov
mov
int

edx, tam_op
ecx, str_op
ebx, 1
eax, 4
0x80

; le^ operador
mov
mov
mov
mov
int

edx, MAX_BUFFER
ecx, buffer
ebx, 0
eax, 3
0x80

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

; BLOCO 2
; Executa a operacao
mov

bx, [buffer] ; le^ o caracter do "operador"

cmp
je

bl, '+'
soma

cmp
je

bl, '-'
subtrai

cmp
je

bl, '*'
multiplica

cmp
je

bl, '/'
divide

cmp
byte[formato], 'i'
jne erro_operador
cmp
je

bl, '|'
bitwise_or

cmp
je

bl, '&'
bitwise_and

cmp
je

bl, '^'
bitwise_xor

cmp
je

bx, 'SL'
shift_left

cmp bx, 'SR'


je
shift_right
cmp
je

bx, 'RL'
roll_left

cmp
je

bx, 'RR'
roll_right

; se nao for nenhum operador, o "resultado" e' zero


operador_invalido:
xor
xor

eax, eax
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'

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

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]
Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

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
je

ebx, 0
erro_overflow

div
mov
jmp

ebx
[resultado], eax
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]
Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

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

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

; 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
mov
mov
mov
int

edx, 8
ecx, buffer
ebx, 1
eax, 4
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
mov
mov
mov
int

edx, tam_eol
ecx, str_eol
ebx, 1
eax, 4
0x80

ret

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

;============================================================================
;#### Funcao "pede_num" ###################################################
;============================================================================
; Recebe dois argumentos e devolve em eax o numero lido
; eax: tamanho str
; ebx: str
pede_num:
mov
mov
mov
mov
int

edx, eax
ecx, ebx
ebx, 1
eax, 4
0x80

; le^ o numero escrito pelo utilizador para "buffer"


mov
mov
mov
mov
int

edx, MAX_BUFFER
ecx, buffer
ebx, 0
eax, 3
0x80

dec
mov

eax
[tam_buffer],eax

; converte o numero em "buffer" de string em hexadecimal


; para numero inteiro
xor
xor
xor
mov
cld
mov
jecxz

eax, eax
ebx, ebx
edx, edx
esi, buffer
ecx, [tam_buffer]
pede_num_fim

pede_num_conv:
lodsb
cmp
jbe
add

al, '9'
pede_num_digito
al, 9

and
shl
rcl
shl
rcl
shl
rcl
shl
rcl

al, 0xF
ebx, 1
edx, 1
ebx, 1
edx, 1
ebx, 1
edx, 1
ebx, 1
edx, 1

add
loop

ebx, eax
pede_num_conv

pede_num_digito:

pede_num_fim:
; copia o resultado para eax e retorna

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

mov
ret

eax, ebx

conv_num:
; transforma "resultado" em string
mov
mov
mov
cld
xor

ecx, 8 ; 4 bytes em [resultado] => 8 digitos hexadecimais


edi, buffer
ebx, eax

rol
mov
and
cmp

ebx, 4
eax, ebx
eax, 0xF
eax, 0x9

jbe

escreve_digito

add

al, 'A'-0xA

jmp

escreve_prox

add

al, '0'

eax, eax

escreve_conv:

escreve_digito:

escreve_prox:
stosb
loop
ret

escreve_conv

mov
mov
mov
mov

edx, tam_erro_overflow
ecx, str_erro_overflow
ebx, 1
eax, 4

int

0x80

mov
mov
int

ebx, 0
eax, 1
0x80

mov
mov
mov
mov

edx, tam_erro_operador
ecx, str_erro_operador
ebx, 1
eax, 4

int

0x80

mov
mov
int

ebx, 0
eax, 1
0x80

erro_overflow:

erro_operador:

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

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.

Trabalho prtico de Arquitectura de Computadores

Universidade Lusfona de Lisboa

Trabalho realizado por:


Filipe Custdio (a20090639)
Guilherme Portalegre (a20091469)
Paulo Fernandes (a20093093)
Erivaldo Silva (a20095851)

Trabalho prtico de Arquitectura de Computadores