section .data
 menu db "Menu de Calculadora", 10, \
   "1. Suma (50+10)", 10, \
   "2. Resta (50-10)", 10, \
   "3. Multiplicacion (50*10)", 10 \
 ;La diagonal invertida sirve para poder ordenar el codigo en diferentes lineas 
 ;sin perder la pertenencia de la variable que se le esta asignando un valor

 menu_len equ $ - menu

 resp db "El resultado de la operacion es: ", 0
 resp_len equ $ - resp

 error_msg db "Operacion invalida o inexistente. Ejecuta de nuevo", 10, 0
 error_len equ $ - error_msg


section .bss
 choice resb 5
 ;Este bufer reservara los bytes para lo que ingrese el usuario

 buffer resb 20
 ;Este buffer reservara 20 bytes para formatear a ASCII el resultado final


section .text
 global_start

_start:
 ;Imprimir el menu del programa
 mov rax, 1
 mov rdi, 1
 mov rsi, menu
 mov rdx, menu_len
 syscall

 ;Leer lo que el usuario eligio
 mov rax, 0
 mov rdi, 0
 mov rsi, choice
 mov rdx, 5
 syscall

 ;Justo despues de la ejecucion, choice guardo el caracter que el usuario ingreso, 
 ;en caso de que haya existido un enter tambien lo guarda

 movzx rcx, [choice]
 ;movzx copia el primer byte del buffer en el registro rxc, rellenando el resto con 0

 ;Definicion de los valores para la operacion (constantes fijas)
 mov r8, 50
 mov r9, 10


 ;Comparacion de la opcion que eligio 
 cmp rcx, "1"
 ;cmp compara el valor del registro rcx, con los codigos en texto elegidos
 je hacer_suma
 ; je (Jump if equal), si es igual salta a la etiqueta definida


 cmp rcx, "2"
 je hacer_resta

 cmp rcx, "3"
 je hacer_multi

;Bloques de operaciones matematicas
hacer_suma:
  mov rax, r8
  add rax, r9
  jmp show_op 
  ; justo despues de hacer la operacion, hacemos un salto a la etiqueta definida,
  ;esto con el fin que no continue la ejecucion de las demas operaciones

hacer_resta:
  mov rax, r8
  sub rax, r9
  jmp show_op

hacer_multi:
  mov rax, r8
  mov rbx, r9
  mul rbx
  ;Se realiza la multiplicacion de rax por rbx y el resultado se almacena en rax. 
  jmp show_op


invalido:
  ;Este bloque se ejecutara cuando no exista ninguna opcion valida
  mov rax, 1
  mov rdi, 1
  mov rsi, error_msg
  mov rdx, error_len
  syscall
  jmp exit_program

show_op:
  ;Bloque para la impresion del resultado 
  mov rbx, rax
  ;respaldamos el resultado de la operacion en otro registro 

  ;Imprimimos mensaje decorativo
  mov rax, 1
  mov rdi, 1
  mov rsi, resp
  mov rdx, resp_len
  syscall


  ;Proceso de conversion del numero a ASCII
  mov rax, rbx
  ;recuperamos el resultado de la operacion en el registro rax
  lea rsi, [buffer + 19]
;apuntamos el puntero para la conversion al final del buffer que reservamos
  mov byte [rsi], 10
;agregamos un byte adicional para el salto de linea
  mov rbx, 10

  
.convert_loop:
 ;Funcion de conversion de caracteres numeros a ASCII
 xor rdx, rdx 
 ;Limpiar el registro de rdx antes de usarlo
 div rbx 
 ;Dividimos lo que se almacena en el registro rax /10. el cociente queda en rax y el residuo en rdx
 add dl, '0'
 ;Convertimos el residuo numerico a su caracter en ASCII ('0'- '9')
 dec rsi
 ;Retrocedemos una posicion en el buffer para llenar de derecha a izquierda
 mov [rsi], dl 
 ;Guardamos el caracter convertido en la posicion actual del buffer
 test rax, rax
 ;Evaluar si nuestro cociente llega a 0
 jnz .convert_loop
 ;Si nuestro cociente no es 0, repetimos el ciclo convert_loop
 ;Calculos de bytes que ocupa e numero convertido a ASCII
 lea rdx, [buffer + 20]
 ;Obtener la posicion final del buffer 
 sub rdx, rsi
 ;restamos el inicio actual para obtener los bytes restantes en una longitud exacta
 ;Imprimimos los caracteres
 mov rax, 1
 mov rdi, 1

 syscall

exit_program
 mov rax, 60
 mov rdi, 0
 syscall

 





Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: