Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Strabush

[Assembly486] Ajuda com calculadora

Mensagens Recomendadas

Strabush

Bem, tenho um projecto pra terminar e no entanto enquanto o fazia deparei-me com certas situações limitantes no qual impediram a perfeição total do trabalho.

O objectivo é criar uma calculadora que faça operações aritméticas (+, -, *, /), lógicas (XOR, AND, OR) e também SL, SR, RL e RR. Consegui fazer a calculadora com as operações aritmeticas e mais o SL e SR. Falta XOR, AND, OR; RL, RL.

Para facilitar a vossa compreensão, vou enumerar as dúvidas:

1- Adicionar as operações XOR, AND, OR; RL, RL.

2- Fazer com que o programa detecte e indique no ecrã as situações de overflow.

3- O programa produz resultado em Hexa, como faço para po-lo em inteiro?

Se alguém pudesse ajudar agradecia imenso.

Caso prefiram, aqui têm o programa feito até agora:

section .data

MAX_PALAVRA	equ	40

s1	 db	0xa,"Introduza num: "
ts1	 equ	$ - s1
s3	 db	0xa,"Resultado: "
ts3	 equ	$ - s3
s4	 db	0xa,"Introduza o operador (+,-,*,/,&,SL,SR): "
ts4	 equ	$ - s4
s5	db	0xa,"Operador inválido",0xA
ts5	equ	$ - s5
linha	db	0xa,0xa
tlinha	equ	$ - linha

num1	dd	0
num2	dd	0
result	dd	0
tamstr	dd	0

section .bss
strnum	resb	MAX_PALAVRA

section .text

global _start

_start:

        ; Pede num1
call	pedeNumero
mov	[num1], ebx

        ; Pede num2
call	pedeNumero
mov	[num2], ebx

        ; Pede operador
mov     edx,ts4
        mov     ecx,s4
        mov     ebx,1   
        mov     eax,4   
        int     0x80    

        mov     edx,MAX_PALAVRA
        mov     ecx,strnum
        mov     ebx,0
        mov     eax,3
        int     0x80

mov	esi, strnum
cld
lodsb
cmp	al, '+'
jne	subtrai
call	fsoma
jmp	escreve

subtrai:
cmp	al, '-'
jne	multiplica
call	fsubtrai
jmp	escreve

multiplica:
cmp	al, '*'
jne	divide
call	fmultiplica
jmp	escreve

divide:
cmp	al, '/'
jne	op_and
call	fdivide
jmp	escreve

op_and:
cmp	al, '&'
jne	op_SL
call	fop_and
jmp	escreve

op_SL:
cmp	al, 'S'
jne	erro_operador
lodsb	; Carrega 2º byte do operador no al
cmp	al, 'L'
jne	op_SR
call	fop_SL
jmp	escreve

op_SR:
cmp	al, 'R'
jne	erro_operador
;call	fop_SR
jmp	escreve

erro_operador:
        ; Mensagem operador inválido
mov     edx,ts5
        mov     ecx,s5
        mov     ebx,1   
        mov     eax,4   
        int     0x80    
jmp	acabou

escreve:
; Transforma resultado em string
mov	ecx, 8
mov	edi, strnum
mov	ebx, [result]
cld
xor 	eax, eax
cicloresult:
rol	ebx, 4
mov	eax, ebx
and	eax, 0x0000000F
cmp	eax, 10
jl	algarismo
add	al, 'A'-10
jmp	fim3
algarismo:
add	al, '0'
fim3:
stosb
loop cicloresult

; Imprime resultado
mov     edx,ts3
        mov     ecx,s3
        mov     ebx,1   
        mov     eax,4   
        int     0x80    

mov     edx,8
        mov     ecx,strnum
        mov     ebx,1   
        mov     eax,4   
        int     0x80    

mov     edx,tlinha
        mov     ecx,linha
        mov     ebx,1   
        mov     eax,4   
        int     0x80    

acabou:        
; Sair do programa passando o controlo ao sistema operativo
        mov     ebx,0
        mov     eax,1
        int     0x80
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Funções	

fsoma:
mov	ebx, [num1]
add	ebx, [num2]
mov	[result], ebx
ret

fsubtrai:
mov	ebx, [num1]
sub	ebx, [num2]
mov	[result], ebx
ret

fmultiplica:
mov	eax, [num1]
mov	ebx, [num2]
mul	ebx
mov	[result], eax
ret

fdivide:
xor	edx, edx
mov	eax, [num1]
mov	ebx, [num2]
div	ebx
mov	[result], eax
ret

fop_and:
mov	ebx, [num1]
and	ebx, [num2]
mov	[result], ebx
ret

; É necessário melhorar, pois o 'num2' pode ser maior que 'cl'
fop_SL:
mov	ebx, [num1]
mov	ecx, [num2]
shl	ebx, cl
mov	[result], ebx
ret

pedeNumero:
mov     edx,ts1
        mov     ecx,s1
        mov     ebx,1   
        mov     eax,4   
        int     0x80    

        mov     edx,MAX_PALAVRA
        mov     ecx,strnum
        mov     ebx,0
        mov     eax,3
        int     0x80
sub	eax, 1
mov     [tamstr],eax

xor	eax, eax
xor	ebx, ebx
mov	esi, strnum
cld
mov	ecx, [tamstr]
ciclonum1:
lodsb
cmp	al, '9'
jg	letra1
and	al, 0xF
jmp	fim1
letra1:
and	al, 0xF
add	al, 9
fim1:
shl	ebx,4
add	ebx, eax
loop	ciclonum1
ret

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
vasco16

:)

Assim derepente, sei que ha regras para haver overflow, acho que se o digito mais significativo do 1º operando for diferente do digito mais significativo do resultado houve overflow (não tenho a certeza) , mas acho que podes pegar nessas regras e aplicar no assembly.

Em relação à tua 3ª questão, o enunciado pede mesmo para converter para inteiro? é que é um pouco inutil, a unica utilidade que vejo é mesmo a percepção humana.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Strabush

Assim derepente, sei que ha regras para haver overflow, acho que se o digito mais significativo do 1º operando for diferente do digito mais significativo do resultado houve overflow (não tenho a certeza) , mas acho que podes pegar nessas regras e aplicar no assembly.

Em relação à tua 3ª questão, o enunciado pede mesmo para converter para inteiro? é que é um pouco inutil, a unica utilidade que vejo é mesmo a percepção humana.

Acho que expressei-me mal. O que quis dizer é que se a pessoa for fazer a conta com decimais, o resultado dá decimal; se fizer com Hex, o resultado dá em Hex.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Strabush

Após muita luta consegui por as operações lógicas e os saltos SL-RL a funcionar, apenas falta as rotações RR-RL.

No entanto ainda falta-me implementar o detector de overflow e alguns detalhes quanto a escola do formato do número.

ps: Tenho o source com as alterações no Linux, e uso dual boot, de momento estou no windows, quando estiver no Linux posto como ficou.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
ricpap

A tua calculadora tem que funcionar com numeros negativos e positivos ou so positivos? E o teu programa nao opera em virgula flutuante, em virgula flutuante tens que mexer no FPU.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Strabush

A tua calculadora tem que funcionar com numeros negativos e positivos ou so positivos? E o teu programa nao opera em virgula flutuante, em virgula flutuante tens que mexer no FPU.

Tive a fazer testes e funcionou com números negativos.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Joao_Ingles

Tenho esse mesmo projecto desenvolvido, queria fazer uma pequena alteração:

em vez dele mostrar o resultado mostrado no ecrã (monitor) no mesmo formato, queria que mostrasse num ficheiro no mesmo formato.

Alguém me pode ajudar??

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.