Ir ao conteúdo
  • Cadastre-se
Henrique Dias_732665

Calculadora em Assembly x86 NASM

Recommended Posts

Olá, estou com problemas nesse código que estão me fazendo perder a cabeça.

1º O fatorial não está funcionando direito. Ele apresenta um valor 15 que eu não sei de onde vem.

2º O cálculo de fibonacci funciona certinho se for executado primeiro, porém ao executar uma operação antes dele, o primeiro valor pedido por exemplo(2+3 na soma) é jogado no final do resultado do fibonacci. 

 

Eis meu código:

SYS_EXIT  equ 1SYS_READ  equ 3SYS_WRITE equ 4STDIN     equ 0STDOUT    equ 1segment .data  msgInicial db "Informe a sequência desejada: ", 0xD,0xA  lenmsgInicial equ $ - msgInicial  msgFinal db "O número é: "  lenmsgFinal equ $- msgFinal  msgCRLF db 0xD,0xA  lenmsgCRLF equ $- msgCRLF  msgErroSequenciaInvalida db "Número de sequência deve ser maior do que zero! ", 0xD,0xA  lenmsgErroSequenciaInvalida equ $ - msgErroSequenciaInvalidasection .data  mensagemtopo: db 13,10,'Selecione uma opção',13,10  tamanhomensagemtopo: equ $-mensagemtopo  opções: db '1 - Soma',13,10,'2 - Multiplicar',13,10,'3 - Fatorial',13,10,'4 - Resto de Divisao',13,10,'5 - Fibonacci',13,10,'9 - Sair',13,10  tamanhoopcoes: equ $-opções  mensagemescolha: db 'Digite a opção desejada: '  tamanhomensagemescolha: equ $-mensagemescolha  msg9 db 10,'Resultado: ',0  lmsg9 equ $ - msg9  mensagemopcaoinvalida: db 10,'ERRO! RTFM!',13,10  tamanhomensagemopcaoinvalida: equ $-mensagemopcaoinvalida  msg4 db 0xA,0xD  len4 equ $- msg4  msg2 db 10,'Entre com o primeiro valor: ',0  lmsg2 equ $ - msg2  msg3 db 10,'Entre com o segundo valor: ',0  lmsg3 equ $ - msg3  msgvalorinvalido db 10,'Valor invalido. Redigite. ',0  lmsgvalorinvalido equ $ - msgvalorinvalido segment .bss  opcao resb 3  resultado resb 20  numero resb 12  num1 resb 20  num2 resb 20  x1 resb 4  x2 resb 4   section .text   global _start    _start:  ;Pede a escolha de uma das opções  mov eax,SYS_WRITE  mov ebx,STDOUT      mov ecx,mensagemtopo  mov edx,tamanhomensagemtopo  int 80h  ;Mostra as opções  mov eax,SYS_WRITE  mov ebx,STDOUT     mov ecx,opções  mov edx,tamanhoopcoes  int 80h  mov eax,SYS_WRITE  mov ebx,STDOUT     mov ecx,mensagemescolha  mov edx,tamanhomensagemescolha  int 80h  ;Grava a opção digitada  mov eax,SYS_READ  mov ebx,STDIN    mov ecx,opcao  mov edx,3  int 80h  mov al,[opcao]  sub al, 30h  cmp al,1  jne nao_e_um ;Pule se não for igual  call soma  jmp _start entrada_valida:  push eax  mov eax, SYS_WRITE  mov ebx, STDOUT  mov ecx, msgFinal  mov edx, lenmsgFinal  int 0x80  pop eax    mov edx,0  mov ecx,0  mov ebx,1 loop_fibonacci:      sub eax,1  cmp eax,0  jz resultado_final  ;move para o próximo termo da sequência  ;ebx => edx => ecx  mov ecx,edx  mov edx,ebx  ; neste ponto temos  ; EBX contém o número anterior (F(n-1))   ; EDX contém o número anterior (F(n-1))   ; ECX contém o número anterior (F(n-2))  ; a intenção é fazer EBX = ECX + EDX  add ebx,ecx ; ebx = ebx + ecx     jmp loop_fibonacci  retmostraBX: ;Função à ser usada pela operaçao da sequência fibonacci  ;EBX contém o resultado F(n)  push eax  push ebx  push ecx  push edx      mov eax,ebx  mov edi,numero  call NumToStr ;Chamada da função de conversão Numero p/ String     ;mostra resultado  mov eax, SYS_WRITE          mov ebx, STDOUT  mov ecx, numero  mov edx, 15  int 0x80   mov eax, SYS_WRITE           mov ebx, STDOUT           mov ecx, msgCRLF  mov edx, lenmsgCRLF  int 0x80   pop edx  pop ecx  pop ebx  pop eax  ret       resultado_final:  call mostraBX  retnao_e_um:  cmp al,2  jne nao_e_dois ;Pule se não for igual  call multiplicacao  jmp _startnao_e_dois:  cmp al,3  jne nao_e_tres ;Pule se não for igual  call fatorial  jmp _start nao_e_tres:  cmp al,4  jne nao_e_quatro ;Pule se não for igual  call divisao  jmp _start nao_e_quatro:  cmp al,5  jne nao_e_cinco ;Pule se não for igual  call fibonacci  jmp _start nao_e_cinco:  cmp al,9  je fim ;Pule se for igual  ;Exibe mensagem se a opção digitada for inválida  mov eax,SYS_WRITE  mov ebx,STDOUT  mov ecx,mensagemopcaoinvalida  mov edx,tamanhomensagemopcaoinvalida  int 80h  jmp _start;Função para saída do programafim:  mov eax,SYS_EXIT    mov ebx,0  int 80hsoma:  ;Mensagem de solicitação do primeiro valor  mov eax, 4  mov ebx, 1  mov ecx, msg2  mov edx, lmsg2  int 80h  ;Gravando o primeiro valor digitado  mov eax, SYS_READ  mov ebx, STDIN    mov ecx, num1  mov edx, 12  int 0x80    ;Mensagem de solicitação do segundo valor  mov eax, 4  mov ebx, 1  mov ecx, msg3  mov edx, lmsg3  int 80h  ;Gravando o primeiro valor digitado  mov eax, SYS_READ    mov ebx, STDIN    mov ecx, num2  mov edx, 12  int 0x80   mov esi,num1  call StrToNum  mov [x1],eax  mov esi,num2  call StrToNum  mov [x2],eax   mov eax,[x1]  mov ebx,[x2]   add eax,ebx   mov edi,resultado  call NumToStr  mov eax,4  mov ebx,1  mov ecx, msg9  mov edx, lmsg9  int 80h  ;Mostrando o resultado da soma  mov eax, SYS_WRITE          mov ebx, STDOUT  mov ecx, resultado  mov edx, 15  int 0x80  ;Quebra de linha  mov eax, SYS_WRITE          mov ebx, STDOUT           mov ecx, msg4            mov edx, len4  int 0x80  mov eax,0  mov ebx,0  mov ecx,0  mov edx,0  retmultiplicacao:  ;Mensagem de solicitação do primeiro valor  mov eax, 4  mov ebx, 1  mov ecx, msg2  mov edx, lmsg2  int 80h  ;Gravando o primeiro valor digitado  mov eax, SYS_READ  mov ebx, STDIN   mov ecx, num1  mov edx, 12  int 0x80    ;Mensagem de solicitação do segundo valor  mov eax, 4  mov ebx, 1  mov ecx, msg3  mov edx, lmsg3  int 80h  ;Gravando o segundo valor digitado  mov eax, SYS_READ   mov ebx, STDIN   mov ecx, num2  mov edx, 12  int 0x80  mov esi,num1  call StrToNum  mov [x1],eax  mov esi,num2  call StrToNum  mov [x2],eax  mov eax,[x1]  mov ebx,[x2]  mul ebx  mov edi,resultado  call NumToStr  mov eax,4  mov ebx,1  mov ecx, msg9  mov edx, lmsg9  int 80h  ;Mostrando o resultado na tela  mov eax, SYS_WRITE         mov ebx, STDOUT  mov ecx, resultado  mov edx, 15  int 0x80  ;Quebra de linha  mov eax, SYS_WRITE          mov ebx, STDOUT          mov ecx, msg4           mov edx, len4  int 0x80  retfatorial:  ;Mensagem de solicitação do primeiro valor  mov eax, 4  mov ebx, 1  mov ecx, msg2  mov edx, lmsg2  int 80h  ;Gravando o primeiro valor digitado  mov eax, SYS_READ  mov ebx, STDIN   mov ecx, num1  mov edx, 12  int 0x80    mov esi,num1  call StrToNum  mov [x1],eax  mov [x2],eax  mov eax,[x1]  mov ebx,[x2]  dec ebx  call cmp  cmp:  cmp ebx,1  jg calc  calc:  mul ebx  dec ebx  jmp cmp  mov edi,resultado  call NumToStr  mov eax,4  mov ebx,1  mov ecx, msg9  mov edx, lmsg9  int 80h  ;print the sum  mov eax, SYS_WRITE         mov ebx, STDOUT  mov ecx, resultado  mov edx, 15  int 0x80  mov eax, SYS_WRITE          mov ebx, STDOUT          mov ecx, msg4           mov edx, len4  int 0x80  retfibonacci:  mov eax,0  mov ebx,0  mov ecx,0  mov edx,0  ;Realizando o pedido do valor  mov eax, SYS_WRITE          mov ebx, STDOUT          mov ecx, msgInicial  mov edx, lenmsgInicial  int 0x80                 ;Gravando o valor digitado  mov eax, SYS_READ  mov ebx, STDIN   mov ecx, numero  mov edx, 12  int 0x80  mov esi,numero  call StrToNum  ;eax contém o número da sequência  cmp eax,1  jnb entrada_valida     ; jump if not below     mov eax, SYS_WRITE          mov ebx, STDOUT          mov ecx, msgErroSequenciaInvalida  mov edx, lenmsgErroSequenciaInvalida  int 0x80  jmp fim  ;chamada das funções para realização do cálculo  call loop_fibonacci  call resultado_final  retdivisao:  ;Mensagem 2  mov eax, 4  mov ebx, 1  mov ecx, msg2  mov edx, lmsg2  int 80h  mov eax, SYS_READ  mov ebx, STDIN   mov ecx, num1  mov edx, 12  int 0x80    ;Mensagem 3  mov eax, 4  mov ebx, 1  mov ecx, msg3  mov edx, lmsg3  int 80h     mov eax, SYS_READ   mov ebx, STDIN   mov ecx, num2  mov edx, 12  int 0x80  mov esi,num1  call StrToNum  mov [x1],eax  mov esi,num2  call StrToNum  mov [x2],eax  mov eax,[x1]  mov ebx,[x2]  mov edx,0  div ebx  mov eax,edx  mov edi,resultado  call NumToStr  mov eax,4  mov ebx,1  mov ecx, msg9  mov edx, lmsg9  int 80h  ;Mostrando a divisao  mov eax, SYS_WRITE         mov ebx, STDOUT  mov ecx, resultado  mov edx, 15  int 0x80  mov eax, SYS_WRITE          mov ebx, STDOUT          mov ecx, msg4           mov edx, len4  int 0x80    ret     StrToNum:            push ebx            push esi            push edi            xor     ebx,ebx         ; ebx vai guardar o número            xor     eax,eax            mov     al,[esi]            cmp     al,'0'            jb      .error  ; JUMP IF BELOW            cmp     al,'9'            jbe     .digit ; jump if below or equal            jmp     .error         .digit:            sub     al,'0'            add     ebx,eax            inc     esi            mov     al,[esi]            cmp     al,'0'            jb      .finish            cmp     al,'9'            ja      .finish            mov     edx,ebx         ; multiply ebx by 10            shl     ebx,3            add     ebx,edx            add     ebx,edx            jmp     .digit         .finish:            mov     eax, ebx            mov     edx, esi            clc            pop     edi            pop esi            pop ebx            ret         .error:            stc ; SET CARRY FLAG (CF) = 1            pop     edi            pop esi            pop ebx            ret    ;**********************************************************************************    ; NumToStr converts the number in eax to the string in any radix approx. [2..26]    ; Arguments:    ;   edi - pointer to the string buffer    ;   eax - number to convert.    ; There is no parameter check, so be careful.    ; returns: edi points to the end of a converted number    ;**********************************************************************************    NumToStr:        mov ecx,10        test  eax,eax        jns   NumToStrU        neg   eax        mov   byte [edi],"-"        inc   edi    NumToStrU:        cmp   eax,ecx        jb    .lessA        xor   edx,edx        div   ecx        push  edx        call  NumToStrU        pop   eax    .lessA:        cmp   al, 10        sbb   al, 69h        das        stosb        mov byte [edi],0        ret

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×