﻿;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; NOMBRE Y APELLIDOS: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

section .data               

section .text            
                         
;Subrutinas de ensamblador que es llaman desde C.
global showChar1, showInt1, executeOperation1, 
global opADD1, opMUL1, opPOW1, opAND1, opNEG1
global changeBase, changeSize


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ATENCIÓN: Recordad que las variables y los parámetros de tipo 'char',
;; en ensamblador se tienen que asignar a registros de tipo db (1 byte):
;; al, ah, bl, bh, cl, ch, dl, dh, sil, dil, ...
;; y las de tipo 'int' se tienen que asignar a registros
;; de tipo dd (4 bytes): eax, ebx, ecx, edx, esi, edi, ....
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Las subrutinas en ensamblador que tenéis que implementar son:
;;   showChar1, showInt1, executeOperation1, 
;;   opADD1_C, pMUL1, opPOW1, opAND1, opNEG1
;;
;; NOTA: Os recomendamos que dejéis las subrutinas showChar1 y showInt1
;; para el final porque son las más difíciles de implementar, mientras
;; utilizad las llamadas a las funciones de C, showChar1_C y showInt1_C.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

extern state, base, baseMaxDigits, size   ;Variables definidas en C que 
extern Z, S, C, V, A1, B1, R1, A4, B4, R4 ;se utilizan en ensamblador.

extern gotoxy_C, printch_C                ;Funciones definidas en C que
                                          ;se llaman desde ensamblador.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Situar el cursor en una fila y una columna de la pantalla
; en función de la fila y columna recibidos como parámetro sobre
; los registros edi y esi, respectivamente,
; llamando a la función gotoxy_C.
;
; Variables utilizadas:
; Ninguna
;
; Parámetros de entrada :
; rdi: (edi) fila
; rsi: (esi) columna
;
; Parámetros de salida:
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
gotoxy:
   push rbp
   mov  rbp, rsp
   ;guardamos el estado de los registros del procesador porque
   ;las funciones de C no mantienen el estado de los registros.
   push rax
   push rbx
   push rcx
   push rdx
   push rsi
   push rdi
   push r8
   push r9
   push r10
   push r11
   push r12
   push r13
   push r14
   push r15

   ; Cuando llamamos a la función gotoxy_C(int row_num, int col_num) desde ensamblador
   ; el primer parámetro (row_num) se tiene que pasar por el registro rdi(edi), y 
   ; el segundo parámetro (col_num) se tiene que pasar por el registro rsi(esi)    
   call gotoxy_C

   pop r15
   pop r14
   pop r13
   pop r12
   pop r11
   pop r10
   pop r9
   pop r8
   pop rdi
   pop rsi
   pop rdx
   pop rcx
   pop rbx
   pop rax

   mov rsp, rbp
   pop rbp
   ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Mostrar un carácter, recibido como parámetro sobre el registro al,
; en la pantalla en la posición donde está el cursor,
; llamando a la función printch_C.
;
; Variables utilizadas:
; Ninguna
;
; Parámetros de entrada :
; rax(al): carácter que queremos mostrar.
;
; Parámetros de salida:
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
printch:
   push rbp
   mov  rbp, rsp
   ;guardamos el estado de los registros del procesador porque
   ;las funciones de C no mantienen el estado de los registros.
   push rax
   push rbx
   push rcx
   push rdx
   push rsi
   push rdi
   push r8
   push r9
   push r10
   push r11
   push r12
   push r13
   push r14
   push r15

   ; Cuando llamamos a la función printch_C(char c) desde ensamblador, 
   ; el parámetro (c) se tiene que pasar por el registro rdi(dil).
   mov  rdi, 0
   mov  dil, al
   call printch_C
 
   pop r15
   pop r14
   pop r13
   pop r12
   pop r11
   pop r10
   pop r9
   pop r8
   pop rdi
   pop rsi
   pop rdx
   pop rcx
   pop rbx
   pop rax

   mov rsp, rbp
   pop rbp
   ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Mostrar un valor de tipo char, BYTE (size=1), recibido como parámetro 
; según la base (base) con la que estemos trabajando a partir de la posición 
; [row,col] de pantalla también recibida como parámetro. 
; 
; El valor se tiene que mostrar escribiendo de derecha a izquierda (comenzando por el
; dígito menos significativo) hasta llenar los baseMaxDigits dígitos
; poniendo ceros si es necesario.
; Antes de mostrar el valor tenemos que borrar el espacio donde tenemos que escribir.
; (El valor más largo que podemos escribir es de 32 dígitos).
; 
; Para obtener cada dígito del valor en la base que estamos trabajando,  
; hay que ir dividiendo el valor recibido por la base.
; El residuo de cada división que hacemos (la operación mod(%)) es el valor 
; del dígito que tendremos que convertir a carácter ASCII, sumando 48 
; (48=código ASCII de '0') si el residuo es un valor entre 0 y 9 o 
; sumando 55 (55=65-10, donde 65=código ASCII de 'A') si es un valor 
; entre 10 y 15 (cuando se muestra en base 16).
; Continuaremos dividiendo el cociente por la base hasta tener todos los dígitos.
;
; Operación DIV: (para datos de tipo BYTE) Si queremos hacer bl/cl:
; Tenemos que poner primero el dividendo (bl) en ax haciendo lo siguiente:
; mov ah, 0
; mov al, bl
; y después hacer la división:
; div cl 
; El resultado de la división (ax/cl) queda de la siguiente forma:
; ah: residuo  (en C bl % cl) 
; al: cociente (en C bl / cl)
;
; Si estamos trabajando en base 10, al final hay que poner el signo, 
; '+' si el valor es positivo o '-' si el valor es negativo.
;
; Variables utilizadas: 
; base, size, baseMaxDigits
;
; Parámetros de entrada :
; rdi: (edi) row: fila donde se tiene que mostrar
; rsi: (esi) col: columna donde se tiene que mostrar (des de la derecha).
; rdx: (dl)  valor que queremos mostrar (value).
;
; Parámetros de salida: 
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
showChar1:

    push rbp
    mov  rbp, rsp
    ;guardamos los registros que modificamos y que no son parám. de salida.
    push rax
    push rbx
    push rcx
    push rdx
    push rsi
    push r8

    mov r8b, dl               ; guardamos dl(value)
    mov bl , dl               ; bl:val = dl:value
    cmp BYTE[base], 10        ; if (base==10 && value<0) 
    jne showChar1_NObase10neg
    cmp dl, 0
    jge showChar1_NObase10neg
    neg bl                    ; val = -value;

  showChar1_NObase10neg:

    mov ecx, esi    ;guardamos el valor de la columna (esi) en ecx.
  ; for (c=7; c<=40; c++) { //borramos el espació donde se tiene que mostrar el valor
    mov esi,7
  showChar1_for:
    cmp esi, 40
    jg  showChar1_endfor

    ;gotoxy: Parámetros de entrada: 
    ; rdi: (edi) fila
    ; rsi: (esi) columna
    ; ya los tenemos en estos registros.
    call gotoxy     ; gotoxy_C(row,c);

    ; printch: Parámetros de entrada: 
    ; rax(al): carácter que queremos mostrar.
    mov al, ' '
    call printch    ; printch_C(' ');
    
    inc esi
    jmp showChar1_for

  showChar1_endfor:
    mov esi, ecx    ; recuperamos el valor de la columna (esi) de ecx.

  ;while (col>7) { //Muestra el valor escribiendo de derecha a izquierda.
  showChar1_while:

    ; CóDIGO QUE SE TIENE QUE IMPLEMENTAR EN ENSAMBLADOR 
    ; --------------------------------------------------
    ; digit = val % base; //%:operación MOD, residuo de la división entera
    ; if (digit < 0) digit=0-digit;
    ; val = val / base;
    ; if (digit>=0  && digit <= 9 ) digit=digit+48; //48=ASCII(0)
    ; if (digit>=10 && digit <= 15) digit=digit+55; //55=ASCII(A)-10
    ; gotoxy_C(row,col);
    ; printch_C(digit);
    ; col--;

    ;jmp showChar1_while

  showChar1_base10sign:
    cmp BYTE[base], 10   ; if (base==10)
    jne showChar1_end

      ;gotoxy: Parámetros de entrada: 
      ; rdi: (edi) fila
      ; rsi: (esi) columna
      ; ya los tenemos en estos registros.
      call gotoxy   ; gotoxy_C(row,c);
      
      mov dl, r8b   ; recuperamos value que teníamos en r8b.     
      cmp dl, 0     ; if (value>0)
      jle showChar1_base10neg

        ; printch: Parámetros de entrada: 
        ; rax(al): carácter que queremos mostrar.
        mov al, '+'
        call printch  ; printch_C(' ');
        jmp showChar1_end

      showChar1_base10neg:
        ; printch: Parámetros de entrada: 
        ; rax(al): carácter que queremos mostrar.
        mov al, '-'
        call printch  ; printch_C(' ');

  showChar1_end:
    pop r8
    pop rsi
    pop rdx
    pop rcx
    pop rbx
    pop rax
    mov rsp, rbp
    pop rbp
    ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Mostrar un valor de tipo int, DWORD (size=4), recibido como parámetro 
; según la base (base) con la que estemos trabajando a partir de la posición 
; [row,col] de pantalla también recibida como parámetro. 
; 
; El valor se tiene que mostrar escribiendo de derecha a izquierda (comenzando por el
; dígito menos significativo) hasta llenar los 4*baseMaxDigits dígitos
; poniendo ceros si es necesario.
; Antes de mostrar el valor tenemos que borrar el espacio donde tenemos que escribir.
; (El valor más largo que podemos escribir es de 32 dígitos).
; 
; Para obtener cada dígito del valor en la base que estamos trabajando,  
; hay que ir dividiendo el valor recibido por la base.
; El residuo de cada división que hacemos (la operación mod(%)) es el valor 
; del dígito que tendremos que convertir a carácter ASCII, sumando 48 
; (48=codi ASCII de '0') si el residuo es un valor entre 0 y 9 o 
; sumando 55 (55=65-10, donde 65=código ASCII de 'A') si es un valor 
; entre 10 y 15 (cuando se muestra en base 16).
; Continuaremos dividiendo el cociente por la base hasta tener todos los dígitos.
;
; Operación DIV: (para datos de tipo DWORD) Si queremos hacer ebx/ecx:
; Tenemos que poner primero el dividendo (ebx) en edx:eax haciendo lo siguiente:
; mov edx, 0
; mov eax, ebx
; y después hacer la división:
; div ecx 
; El resultado de la división (edx:eax/ecx) queda de la siguiente forma:
; edx: residuo  (en C ebx % ecx) 
; eax: cociente (en C ebx / ecx)
;
; Si estamos trabajando en base 10, al final hay que poner el signo, 
; '+' si el valor es positivo o '-' si el valor es negativo.
;
; Variables utilizadas: 
; base, size, baseMaxDigits
;
; Parámetros de entrada:
; rdi: (edi) row: fila donde se tiene que mostrar
; rsi: (esi) col: columna donde se tiene que comenzar a mostrar (des de la derecha).
; rdx: (edx)  valor que queremos mostrar (value).
;
; Parámetros de salida: 
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
showInt1:

    push rbp
    mov  rbp, rsp
    ;guardamos los registros que modificamos y que no son parám. de salida.
    push rax
    push rbx
    push rcx
    push rdx
    push rsi
    push r8

    mov r8d, edx              ; guardamos edx(value)
    mov ebx, edx              ; ebx:val = edx:value
    cmp BYTE[base], 10        ; if (base==10 && value<0) val = -value;
    jne showInt1_NObase10neg
    cmp edx, 0
    jge showInt1_NObase10neg
    neg ebx

  showInt1_NObase10neg:
    mov ecx, esi    ;guardamos el valor de la columna (esi) en ecx.
  ; for (c=7; c<=40; c++) { //borramos el espacio donde se tiene que mostrar el valor
    mov esi,7
  showInt1_for:
    cmp esi, 40
    jg  showInt1_endfor

    ;gotoxy: Parámetros de entrada: 
    ; rdi: (edi) fila
    ; rsi: (esi) columna
    ; ya los tenemos en estos registros.
    call gotoxy     ; gotoxy_C(row,c);

    ; printch: Parámetros de entrada: 
    ; rax(al): carácter que queremos mostrar.
    mov al, ' '
    call printch    ; printch_C(' ');
    
    inc esi
    jmp showInt1_for

  showInt1_endfor:
    mov esi, ecx    ; recuperamos el valor de la columna (esi) de ecx.

  ;while (col>7) { //Mostrar el valor escribiendo de derecha a izquierda.
  showInt1_while:

    ; CóDIGO QUE SE TIENE QUE IMPLEMENTAR EN ENSAMBLADOR 
    ; --------------------------------------------------
    ; digit = val % base; //%:operació MOD, residuo de la división entera
    ; if (digit < 0) digit=0-digit;
    ; val = val / base;
    ; if (digit>=0  && digit <= 9 ) digit=digit+48; //48=ASCII(0)
    ; if (digit>=10 && digit <= 15) digit=digit+55; //55=ASCII(A)-10
    ; gotoxy_C(row,col);
    ; printch_C(digit);
    ; col--;

    ;jmp showInt1_while

  showInt1_base10sign:
    cmp BYTE[base], 10   ; if (base==10)
    jne showInt1_end

      ;gotoxy: Parámetros de entrada: 
      ; rdi: (edi) fila
      ; rsi: (esi) columna
      ; ya los tenemos en estos registros.
      call gotoxy   ; gotoxy_C(row,c);
      
      mov edx, r8d   ; recuperamos value que teníamos en r8d.     
      cmp edx, 0     ; if (value>0)
      jle showInt1_base10neg

        ; printch: Parámetros de entrada: 
        ; rax(al): carácter que queremos mostrar.
        mov al, '+'
        call printch  ; printch_C(' ');
        jmp showInt1_end

      showInt1_base10neg:
        ; printch: Parámetros de entrada: 
        ; rax(al): carácter que queremos mostrar.
        mov al, '-'
        call printch  ; printch_C(' ');

  showInt1_end:
    pop r8
    pop rsi
    pop rdx
    pop rcx
    pop rbx
    pop rax
    mov rsp, rbp
    pop rbp
    ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Llamar a la subrutina para hacer la operación seleccionada.
; La opción seleccionada se recibe como parámetro.
; a: llamar a la función opADD1.
; b: llamar a la función opAND1.
; c: llamar a la función opMUL1.
; d: llamar a la función opPOW1.
; e: llamar a la función opNEG1.
;
; Variables utilizadas: 
; Ninguna
;
; Parámetros de entrada:
; rdi: (dil) operación que tenemos que hacer (carácter entre 'a' y 'e').
;   
; Parámetros de salida: 
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
executeOperation1:

    push rbp
    mov  rbp, rsp
    ;guardamos los registros que modificamos y que no son parám. de salida.

   

  executeOperation1_end:
    mov rsp, rbp
    pop rbp
    ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Si operamos con variables de tipo BYTE (size=1), sumar las variables 
; A1 y B1 y guardar el resultado en la variable R1.
; Si operamos con variables de tipo DWORD (size=4) sumar las variables 
; A4 y B4 y guardar el resultado en la variable R4.
;
; En la operación ADD consideramos todos los bits de resultado: Z, S, C y V.
; Los bits de resultado se tienen que consultar con los saltos condicionales 
; jz/jnz (Z), js/jns (S), jc/jnc (C), jo/jno (V)
; justo después de hacer la operación y antes de que sean modificados por 
; otra instrucción. En el código C no consideremos los bits de resultado.
; 
; Variables utilizadas: 
; size, A1, B1, R1, A4, B4, R4
; Z, S, C i V
; 
; Parámetros de entrada: 
; Ninguno
; 
; Parámetros de salida: 
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
opADD1:

    push rbp
    mov  rbp, rsp
    ;guardamos los registros que modificamos y que no son parám. de salida.

   

  opADD1_end:

    mov rsp, rbp
    pop rbp
    ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Si operamos con variables de tipo BYTE (size=1), hacer la operación AND 
; de las variables A1 y B1 y guardar el resultado en la variable R1.
; Si operamos con variables de tipo DWORD (size=4), hacer la operación AND 
; de las variables A4 y B4 y guardar el resultado en la variable R4.
;
; En la operación AND consideramos los bits de resultado Z y S.
; Los bits de resultado C y V los pondremos siempre a cero ('0').
; Los bits de resultado se tienen que consultar con los saltos condicionales 
; jz/jnz (Z), js/jns (S)
; justo después de hacer la operación y antes de que sean modificados por 
; otra instrucción. En el código C no consideremos los bits de resultado.
;
; Variables utilizadas: 
; size, A1, B1, R1, A4, B4, R4
; Z, S, C i V
; 
; Parámetros de entrada: 
; Ninguno
; 
; Parámetros de salida: 
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
opAND1:

    push rbp
    mov  rbp, rsp
    ;guardamos los registros que modificamos y que no son parám. de salida.

   

  opAND1_end:

    mov rsp, rbp
    pop rbp
    ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Si operamos con variables de tipo BYTE (size=1), multiplicar las 
; variables A1 y B1 y guardar el resultado en la variable R1.
; Si operamos con variables de tipo DWORD (size=4), multiplicar las
; variables A4 y B4 y guardar el resultado en la variable R4.
;
; En la operación MUL NO consideramos los bits de resultado.
; Los bits de resultado los pondremos siempre a cero ('0').
; En el código C no consideremos los bits de resultado.
;
; Variables utilizadas: 
; size, A1, B1, R1, A4, B4, R4
; Z, S, C i V
; 
; Parámetros de entrada: 
; Ninguno
; 
; Parámetros de salida: 
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
opMUL1:

    push rbp
    mov  rbp, rsp
    ;guardamos los registros que modificamos y que no son parám. de salida.

   

  opMUL1_end:

    mov rsp, rbp
    pop rbp
    ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Si operamos con variables de tipo BYTE (size=1), hacer la potencia de 
; las variables A1 y B1 (A1 ^ B1) y guardar el resultado en la variable R1.
; Si operamos con variables de tipo DWORD (size=4), hacer la potencia de
; las variables A4 y B4 (A4 ^ B4) y guardar el resultado en la variable R4.
; 
; Per fer el càlcul, multiplicar B vegades A (per fer 2^3 farem 2*2*2=8).
; 
; En la operación POW NO consideramos los bits de resultado.
; Los bits de resultado los pondremos siempre a cero ('0').
; En el código C no consideremos los bits de resultado.
;
; Variables utilizadas: 
; size, A1, B1, R1, A4, B4, R4
; Z, S, C i V
; 
; Parámetros de entrada: 
; Ninguno
; 
; Parámetros de salida: 
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
opPOW1:

   push rbp
   mov  rbp, rsp
   ;guardamos los registros que modificamos y que no son parám. de salida.

   

  opPOW1_end:

   mov rsp, rbp
   pop rbp
   ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Si operamos con variables de tipo BYTE (size=1), hacer la operación NEG 
; de la variable A1 y guardar el resultado en la variable R1.
; Si operamos con variables de tipo DWORD (size=4), hacer la operación NEG 
; de la variable A4 y guardar el resultado en la variable R4.
; 
; Para hacer la operación NEG hay que canviar el signo de A1 o A4.
;
; En la operación NEG consideramos totos los bits de resultado: Z, S, C y V.
; Los bits de resultado se han de consultar en los saltos condicionales
; jz/jnz (Z), js/jns (S), jc/jnc (C), jo/jno (V)
; justo después de hacer la operación y antes de que se modifiquen por otra instrucción.
; En el código C no consideramos los bits de resultado.
; 
; Variables utilizadas: 
; size, A1, R1, A4, R4
; Z, S, C i V
;
; Parámetros de entrada: 
; Ninguno
;   
; Parámetros de salida: 
; Ninguno:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
opNEG1:

    push rbp
    mov  rbp, rsp
    ;guardamos los registros que modificamos y que no son parám. de salida.

   

  opNEG1_end:

    mov rsp, rbp
    pop rbp
    ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Cambiar el valor de las variables base y baseMaxDigits en función de 
; la opción escogida.
; La opción seleccionada se recibe como parámetro.
; 1: base=2,  baseMaxDigits=8
; 2: base=8,  baseMaxDigits=4
; 3: base=10, baseMaxDigits=3
; 4: base=16, baseMaxDigits=2
;
; Variables utilizadas: 
; base
; baseMaxDigits
;
; Parámetros de entrada: 
; rdi: (dil) carácter leído
;
; Parámetros de salida: 
; Ninguno
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
changeBase:

    push rbp
    mov  rbp, rsp
    ;guardamos los registros que modificamos y que no son parám. de salida.

  changeBase_1:
    cmp dil, '1'              ; case '1':
    jne changeBase_2

    mov BYTE[base], 2         ; base=2
    mov BYTE[baseMaxDigits], 8; baseMaxDigits=8
    jmp changeBase_end        ; break

  changeBase_2:
    cmp dil, '2'              ; case '2':
    jne changeBase_3

    mov BYTE[base], 8         ; base=8
    mov BYTE[baseMaxDigits], 4; baseMaxDigits=4
    jmp changeBase_end        ; break

  changeBase_3:
    cmp dil, '3'              ; case '3':
    jne changeBase_4

    mov BYTE[base], 10        ; base=10
    mov BYTE[baseMaxDigits], 3; baseMaxDigits=3
    jmp changeBase_end        ; break

  changeBase_4:
    cmp dil, '4'              ; case '4':
    jne changeBase_end        ; break

    mov BYTE[base], 16        ; base=16
    mov BYTE[baseMaxDigits], 2; baseMaxDigits=2
    
  changeBase_end:
    mov rsp, rbp
    pop rbp
    ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Cambiar el valor de la variable size en función de la opción escogida.
; La opción seleccionada se recibe como parámetro.
; x: size=1
; y: size=4
; 
; Variables utilizadas: 
; size
;
; Parámetros de entrada: 
; rdi: (dil) carácter leído
;   
; Parámetros de salida: 
; Ninguno:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
changeSize:

    push rbp
    mov  rbp, rsp
    ;guardamos los registros que modificamos y que no son parám. de salida.

  changeSize_X:
    cmp dil, 'x'        ; case 'x':
    jne changeSize_Y

    mov BYTE[size], 1   ; size=1
    jmp changeSize_end  ; break
    
  changeSize_Y:
    cmp dil, 'y'        ; case 'y':
    jne changeSize_end  ; break

    mov BYTE[size], 4   ; size=4;
    
  changeSize_end:
    mov rsp, rbp
    pop rbp
    ret

;-----------------------------------------------------------------------
