;Lourdes Marisol Castillo Caamal
;Carolina Maribel Fernández Uicab 
;Angel Iram Torres Salazar
section .data
    ;Mensaje de ingresar el primer numero 
    num1 db "Ingresa el primer numero: ",10
    num1_len equ $ - num1
 
    ;Mensaje de ingresar segundo numero 
    num2 db "Ingresa un segundo numero (debe ser menor que el primer número capturado): ",10
    num2_len equ $ - num2
 
    ;Mensaje de seleccion de opción sume o resta
    opcion db "Ingresar 1 si desea sumar los dos números ingresados o 2 si los desea restar: ",10
    opcion_lem equ $ - opcion
 
    ;Leer el valor 1
    valor1 times 64 db 0 ;reservamos 64 bytes 
    valor1_lem equ $ - valor1
 
    ;Leer el valor 2
    valor2 times 64 db 0 ;reservamos 64 bytes
    valor2_lem equ $ - valor2
 
    ;Leer el seleccion
    selc times 2 db 0 ;solo leeemos el valor y el enter
 
    ;Mensaje de resultado dela suma
    msgs db "El resultado de la suma es: ",10
    msgs_lem equ $ - msgs
 
    ;Mensaje de resultado de la resta
    msgr db "El resultado de la resta es: ",10
    msgr_lem equ $ - msgr
 
    ;Reserva del resultado delimita a 64 byts pero podemos ponerlo en equ $ - resultado
    resultado times 64 db 0
    resultado_lem equ 64
 
    ;Mensaje de error por opcion invalida
    msge db "Error: opcion invalida. Solo se permite 1 o 2.",10
    msge_lem equ $ - msge
 
section .text
    global _start
 
_start:
    ;mensaje de solicitud del primer numero
    mov rax, 1 ;imprimir
    mov rdi, 1 ;en pantalla
    mov rsi, num1
    mov rdx, num1_len
    syscall
 
    ;leemos el primer numero, un caracter a la vez hasta el Enter
    mov rsi, valor1 ;es el inicio dle buffer en el valor que se ha leido
 
    
leer1: ;se coloca un ciclo para leer cada numero uno por uno
    mov rax, 0 ;llamado a leer
    mov rdi, 0 ;teclado estandar
    mov rdx, 1 ;un solo caracter
    syscall
 
    mov al, [rsi] ;CONTENIDO EN CORCHETES NO LA DIRECCION
    cmp al, 10    ;10 es el Enter es decir cuando acaba el ciclo
    je fin_leer1  ;si es Enter sale del ciclo
    inc rsi       ;si no avanza la siguiente posicion
    jmp leer1     ;y repite hasta teneer el enter
fin_leer1:
 
    ;solicitud del segundo numero
    mov rax, 1 ;imprimir
    mov rdi, 1 ;en pantalla
    mov rsi, num2
    mov rdx, num2_len
    syscall
 
    ;leemos el segundo numero, un caracter a la vez hasta el Enter
    mov rsi, valor2
leer2:
    mov rax, 0 ;llamado a leer
    mov rdi, 0 ;teclado estandar
    mov rdx, 1 ;un solo caracter
    syscall
 
    mov al, [rsi] ;CONTENIDO EN CORCHETES NO LA DIRECCION
    cmp al, 10    ;10 es el enter es decir cuando acaba el ciclo
    je fin_leer2  ;si es si sale del ciclo
    inc rsi       ;si no avanza a la siguiente posicióne
    jmp leer2     ;y se repite hasta optener el enter 
fin_leer2:
 
pedir_opcion:
    ; mostrar seleccion de opcion suma o resta
    mov rax, 1 ;imprimir
    mov rdi, 1 ;en pantalla
    mov rsi, opcion
    mov rdx, opcion_lem
    syscall
 
    ;leemos el digito de la opcion
    mov rax, 0 ;sysread
    mov rdi, 0 ;teclado estandar
    mov rsi, selc
    mov rdx, 1
    syscall
 
    ;convertir el segundo numero de ASCII a numero (todos sus digitos) considerar que como vamos a trabajar la suma y resta en rax guardamos primero el segundo numero
    mov rsi, valor2
    xor rax, rax ;acumulador en 0
    
convertir2:
    xor rdx, rdx ;limpiamos rdx
    mov dl, [rsi] ;tomamos un caracter 
    cmp dl, 10    ;si es el Enter termina
    je fin2       
    sub dl, '0'   ;convertimos el digito a ASCII a digito
    mov rcx, rax  ;acumulado * 10 usando solo add
    add rax, rax  ;x2 acumulador
    add rax, rax  ;x4 acumulador 
    add rax, rcx  ;x5 acumulador
    add rax, rax  ;x10 acumulador
    add rax, rdx  ;+ digito suma el siguiente digito para la posición
    inc rsi       ;siguiente caracter
    jmp convertir2 ;se repite hasta el enter que es 10
fin2:
    mov rbx, rax            ;guarda el segundo numero en rbx
 
    ;convertir el primer numero de ASCII a numero (todos sus digitos)
    mov rsi, valor1
    xor rax, rax ;acumulador en 0
    
convertir1:
    xor rdx, rdx ;limpiar rdx
    mov dl, [rsi] ;tomamos un caracter
    cmp dl, 10   ;si es enter termina y no hace ciclos de acomodar los valores
    je fin1
    sub dl, '0'  ;convertir el digito a ASCII a digito
    mov rcx, rax ;acumulador * 10 usando solo add
    add rax, rax ;x2 acumulador
    add rax, rax ;x4 acumulador
    add rax, rcx ;x5 acumulador
    add rax, rax ;z10 acumulador
    add rax, rdx ;+ digito suma el siguiente digito para la posición
    inc rsi      ;siguiente caracter
    jmp convertir1 ;se repite hasta el enter que es 10
fin1:                       ;el primer numero se guarda en rax
 
    ;Convertir opcion a numero
    xor rcx, rcx ;limpiamos osea volver en 0
    mov cl, [selc] ;tomamos el contenido y lo baseamos a cl que como solo es 1 digito con el enter podemos ponerle en la parte baja
    sub cl, '0' ;lo convertimos a ASCII
 
seleccion: 
    ;Comprobar opcion
    cmp cl, 1 ;si es 1 lo sumamos
    je suma ;lo lleva a suma
 
    cmp cl, 2 ;si es 2 lo resta
    je resta ;lo lleva a resta
 
    ;si no es 1 ni 2 muestra el mensaje de error
    mov rax, 1              ;imprimir
    mov rdi, 1              ;en pantalla
    mov rsi, msge           ;mensaje de error
    mov rdx, msge_lem
    syscall
 
    ;terminar
    mov rax, 60
    mov rdi, 0 
    syscall
 
suma:
    add rax, rbx            ;sume primero + segundo
    mov rbx, rax            ;guardamos el resultado en rbx, pues el syscall modifica rax
 
    mov rax, 1 ;imprimir
    mov rdi, 1 ;en pantalla
    mov rsi, msgs ;mensaje de que es suma
    mov rdx, msgs_lem
    syscall
 
    mov rax, rbx            ;regresamos el valor en rax
    jmp imprimir            ;y lleva a imprimir para no ir a la resta ademas que deben contabilisar las unidades decenas y centenas de la respuesta 
 
resta:
    sub rax, rbx            ;resta del primero - segundo
    mov rbx, rax            ;guardamos el resultado en rbx, pues el syscall modifica rax
 
    mov rax, 1 ;imprimir
    mov rdi, 1 ;en pantalla
    mov rsi, msgr ;mensaje de que es resta
    mov rdx, msgr_lem
    syscall
 
    mov rax, rbx            ;regresamso el valor a rax y directamente pasa a imprimir es decir sigue con el programa
 
imprimir:
    mov rbx, 10             ;Divisor 
    mov rsi, resultado_lem  ;Cuanto va imprimer/tamaño
    mov rcx, 0              ;Contador cuantos digitos almacenamos 
 
    ;El resultado se convierte de derecha a izquierda
    convertir:
        xor rdx, rdx        ;Limpiar y colocar 0
        div rbx             ;Dividir
 
        add dl, '0'         ;Convertir residuo a caracter ASCII
        dec rsi             ;Retroceder una posicion
        mov [resultado + rsi], dl ;Guarda el caracter en resultado sumando el retroceso de posición
        inc rcx             ;Contador del los digitos
 
        test rax, rax       ;Comprueba que el cociente es cero
        jnz convertir       ;Si no es cero repite, cuando todo se almaceno y es 0 sale para imprimir
   
    ;Impresion del resultado
    mov rax, 1
    mov rdi, 1
    lea rsi, [resultado + rsi] ;Movemos los datos a rsi para su impresión
    mov rdx, rcx            ;Cantidad real de digitos
    syscall
 
    ;TERMINAR PROGRAMA
    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: