Ir ao conteúdo
  • Cadastre-se

Calculadora em Assembly x86 NASM


Posts recomendados

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
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!