Fundamentos de Arquitectura de Computadores: Representación Numérica, MIPS y Gestión de Memoria

Clasificado en Informática

Escrito el en español con un tamaño de 20,91 KB

Sistemas de Representación Numérica

Representación Signo-Magnitud

  • El bit más significativo (MSB) indica el signo: 0 si es positivo, 1 si es negativo.
  • Rangos: De -(2^(n-1) - 1) hasta (2^(n-1) - 1).

Representación Complemento a 1 (C1)

  • Si el número es positivo, se deja igual.
  • Si el número es negativo, se cambian los 0 por 1 y los 1 por 0 (complemento bit a bit).
  • Rangos: De -(2^(n-1) - 1) hasta (2^(n-1) - 1).

Representación Complemento a 2 (C2)

  • Si el número es positivo, se deja igual.
  • Si el número es negativo, se calcula su Complemento a 1 y se le suma 1.
  • Rangos: De -2^(n-1) hasta (2^(n-1) - 1).

Representación por Exceso

  • Se suma un valor de exceso (generalmente 2^(n-1) - 1) al número original.
  • Rangos: De -(2^(n-1) - 1) hasta 2^(n-1).

Representación en Coma Flotante (IEEE 754)

Un número en coma flotante se representa como: Número = (-1)^S * M * 2^Exp.

Precisión Simple (32 bits)

  • S (Signo): 1 bit.
  • Exp (Exponente): 8 bits. El exponente real se obtiene restando un bias de 127 (Exp_real = Exp_almacenado - 127).
  • M (Mantisa): 23 bits. Se asume un bit implícito '1' antes de la coma para números normalizados (1.M).

Precisión Doble (64 bits)

  • S (Signo): 1 bit.
  • Exp (Exponente): 11 bits. El exponente real se obtiene restando un bias de 1023 (Exp_real = Exp_almacenado - 1023).
  • M (Mantisa): 52 bits. Se asume un bit implícito '1' antes de la coma para números normalizados (1.M).

Fórmula General para Calcular el Valor

N = (-1)^S * 1.M * 2^(Exp_almacenado - Bias) (donde Bias es 127 para precisión simple o 1023 para doble precisión).

Casos Especiales en Coma Flotante (Precisión Simple)

  • Si el exponente es 255 (todos unos):
    • Si la mantisa (M) es 0, el valor será ±Infinito (dependiendo del bit de signo S).
    • Si la mantisa (M) no es 0, el valor será NaN (Not a Number).
  • Si el exponente está entre 1 y 254 (normalizado):
    • Valor = (-1)^S * 1.M * 2^(Exp_almacenado - 127).
  • Si el exponente es 0 y la mantisa (M) no es 0 (denormalizado):
    • Valor = (-1)^S * 0.M * 2^(-126).

Problemas de Camino de Datos

Se trabaja siempre en el flanco de subida del reloj. Los ejemplos asumen dos ciclos de reloj por operación.

Ejemplo 1: R1 = R2 + Ri0

Primero, los valores se convierten a binario y se realiza el cálculo.

  1. Ciclo 1:
    • Los dos valores se cargan en sus respectivos registros.
    • Primer flanco de subida de reloj: Se habilita la salida de R2 (TB, En-A), y el valor de R2 se transfiere al registro A.
    • El Bus de Datos toma el valor de A.
    • Se establece SB = 0x02 (indicando que el dato proviene de R2).
  2. Ciclo 2:
    • Segundo flanco de subida de reloj: El Bus de Datos toma el valor 0xA6.
    • Se habilita la entrada de Ri0 (TRi0).
    • Se selecciona la operación de suma (OP: suma).
    • Se habilita la entrada del registro temporal (En-Tmp) y la entrada de Ri (EN-Ri).
    • El resultado se almacena en Rtmp.
    • Los flags de estado (Z=0, C=1, V=1) se actualizan.
  3. Ciclo 3:
    • Tercer flanco de subida de reloj: El Bus de Datos toma el valor 0x10.
    • Se establece SB = 0x01 (indicando que el dato se dirige a R1).
    • Se habilita la entrada de B (En-B) y la salida de Rtmp (T-Tmp).
    • El valor 0x10 se carga en R1.

Ejemplo 2: R1 = Ri1 (0x02) + R2 (0xFF)

Cada número hexadecimal se carga en su respectiva posición.

  1. Ciclo 1:
    • Primer flanco de subida de reloj: El Bus de Datos toma el valor 0xFF.
    • Se establece SB = 0x02 (indicando que el dato proviene de R2).
    • Se habilita la salida de R2 (TB) y la entrada de A (En-A). El valor 0xFF se carga en A.
  2. Ciclo 2:
    • Segundo flanco de subida de reloj: El Bus de Datos toma el valor 0x02.
    • Se habilita la entrada de Ri1 (TRi1).
    • Se selecciona la operación de suma (Op=suma).
    • Se habilita la entrada del registro temporal (En-Tmp) y la entrada de Ri (En-Ri).
    • El resultado 0x01 se almacena en Rtmp.
    • Los flags de estado (Z=0, C=1, V=1) se actualizan.
  3. Ciclo 3:
    • Tercer flanco de subida de reloj: El Bus de Datos toma el valor 0x01.
    • Se establece SB = 0x01 (indicando que el dato se dirige a R1).
    • Se habilita la entrada de B (En-B) y la salida de Rtmp (Ttmp).
    • El valor 0x01 se carga en R1.

Problemas de Instrucciones MIPS

Fase de Captación (FETCH) - Común para todas las instrucciones

  1. S1: MAR <- PC (Cmar, Tpc)
  2. S2: MBR <- Memoria Principal (MP) y PC <- PC + 4 (S, L, Cmbr1, Cpc1)
  3. S3: RI <- MBR (Tmbr2, Cri)
  4. S4: Decodificación (-)

Ejemplos de Instrucciones y sus Pasos de Ejecución

1. ADD $t0, $t1, $t2

  • Código Binario: 000000 01001 01010 01000 00000 100000
  • Código Hexadecimal: 0x012A4020
  • Pasos de Ejecución (Sx): R8 <- R9 + R10 (T5, Cind, AluOp=100000, CB=1, MA=0, MB=0, Ra=01001, Rb=01010, Rc=01000)

2. ADDI $s0, $s1, 0x70F0

  • Código Binario: 001000 10001 10000 0111000011110000
  • Código Hexadecimal: 0x223070F0
  • Pasos de Ejecución (Sx):
    • RT1 <- RI (C9 o CRt1, Tri)
    • R16 <- R17 + RT1 (T5, Cind, AluOp:100000, CB=1, MA=1, MB=0, Rb=10001, Rc=10000)

3. LW $t0, 0x0004

  • Código Binario: 100011 00000 01000 0000000000000100
  • Código Hexadecimal: 0x8C080004
  • Pasos de Ejecución (Sx):
    • MAR <- RI (Cmar, Ti)
    • MBR <- MP (S, L, Cmbr1)
    • R8 <- MBR (Tmbr2, CB, Rc=01000)

4. LW $t0, 4($s0)

  • Código Binario: 100011 10000 01000 0000000000000100
  • Código Hexadecimal: 0x8E080004
  • Pasos de Ejecución (Sx):
    • RT1 <- RI (Ti, C9 o CRT1)
    • MAR <- R4 + RT1 (Cmar, T5, MA=1, MB=0, Aluop=100000, Rb=10000)
    • MBR <- MP (S, L, Cmbr1)
    • R8 <- MBR (CB, Tmbr2, Rc=01000)

5. SW $t0, 0x0008

  • Código Binario: 101011 00000 01000 0000000000001000
  • Código Hexadecimal: 0xAC080008
  • Pasos de Ejecución (Sx):
    • MAR <- RI (Ti, Cmar)
    • MBR <- R8 (Ra=01000, Ti, Cmbr2)
    • MP <- MBR (Tmbr1, S)

6. SLL $t1, $t0, 2

  • Código Binario: 000000 00000 01000 01001 00010 000000
  • Código Hexadecimal: 0x00084880
  • Pasos de Ejecución (Sx):
    • RT1 <- RI (Ti, C9 o CRT1)
    • R9 <- R8 + RT1 (MA=1, MB=0, CB, Aluop=000000, T5, Cind, Rb=01000, Rc=01001)

7. SRA $t1, $t0, 1

  • Código Binario: 000000 00000 01000 01001 00001 000011
  • Código Hexadecimal: 0x00084843
  • Pasos de Ejecución (Sx):
    • RT1 <- RI (Ti, C9 o CRT1)
    • R9 <- R8 + RT1 (Mismas que en SLL, pero cambiando: Aluop=000011)

8. J 0x000010

  • Código Binario: 000010 00000000000000000000010000
  • Código Hexadecimal: 0x08000010
  • Pasos de Ejecución (Sx): PC <- RI (Tj, Cpc2)

9. JR $ra

  • Código Binario: 000000 11111 00000 00000 00000 001000
  • Código Hexadecimal: 0x03E00008
  • Pasos de Ejecución (Sx): PC <- R31 (Ra=11111, T1, Cpc2)

10. ORI $t0, $t2, 0x00A1

  • Código Binario: 001101 01010 01000 0000000010100001
  • Código Hexadecimal: 0x354800A1
  • Pasos de Ejecución (Sx):
    • RT1 <- RI (C9 o CRT1, Ti)
    • R8 <- RT1 OR R10 (MA=1, MB=0, CB, T5, Cind, Aluop=100101, Rb=01010, Rc=01000)

Problemas de Memoria

Cálculo de Chips y Módulos

  • Número de chips: (Bits del bus de datos / Ancho de datos del chip)
  • Ejemplo: Capacidad Total = 512KB, Bus de datos = 16 bits, Chip = 64Kx8.
    • Número de Chips = 16 bits / 8 bits = 2 chips.
  • Número de módulos: (Capacidad Total de la memoria / (Capacidad de un chip * Número de chips por módulo))
  • Ejemplo Anterior:
    • Número de Módulos = 512KB / (64KB * 2 chips) = 512KB / 128KB = 4 Módulos.

Cálculo de Bits para Direccionamiento

  • Bits para direccionar un byte: Si el bus de datos es de 2^x bits, se necesitan x bits.
  • Bits para datos (capacidad del chip): Para 64K, 64K = 2^6 * 2^10 = 2^16, por lo tanto, se necesitan 16 bits para direccionar las celdas dentro del chip.
  • Bits para el módulo: Bits del bus de dirección total - (Bits para direccionar un byte + Bits para datos).

Diseño de la Tabla de Direcciones

Para cada módulo, se debe especificar la primera dirección (todos los bits a 0, excepto los bits del módulo) y la última dirección (todos los bits a 1, excepto los bits del módulo).

Mapa de Memoria

Una línea de dirección de 24 bits se divide en tres secciones:

  1. Módulo: Bits que seleccionan el módulo. Esta línea va a un decodificador, del cual salen tantas líneas como módulos haya, entrando en el módulo por la parte inferior.
  2. Datos: Bits que seleccionan la celda dentro del chip. Esta línea baja y entra por la parte A (extremo izquierdo) del módulo y sale por B (extremo derecho), volviéndose a unir todas para salir por una única salida de X bits (bits de datos).
  3. Byte: Bits que seleccionan el byte dentro de la palabra. Esta línea hace un flanco de bajada y luego sube para salir de ella X bits (bits de byte).

Mapa del Módulo

Dibujar una línea de datos y un decodificador para conectar tantos chips como tenga el programa. Se conectan uno tras otro, seguidos, para acabar uniéndose en una forma de 'C' inversa con salida diagonal de X bits (bits de datos).

Problemas de Tiempos de Acceso

Fórmula del Tiempo Medio de Acceso

T_medio = T_acceso_cache + (1 - P_acierto_cache) * T_acceso_MP

  • T_acceso_cache: Tiempo de acceso a la memoria caché.
  • T_acceso_MP: Tiempo de acceso a la memoria principal.
  • P_acierto_cache: Probabilidad de que el dato esté en la caché (Hit Rate).

Si el tiempo de acceso a la caché es igual al tiempo de ciclo del procesador:

  • T_acceso_cache = 1 / Frecuencia (donde F es la frecuencia del procesador).
  • Conversión: 1 segundo = 1 x 10^9 nanosegundos. Si la frecuencia (F) está en MHz, el resultado estará en nanosegundos.

Fundamentos Teóricos de Arquitectura de Computadores

Funcionamiento de un Computador Von Neumann

Un computador procesa información siguiendo estas fases:

  1. Saber qué proceso realizar: Identificación de la instrucción.
  2. Saber dónde está lo que procesar y dónde almacenarlo: Determinación de direcciones de memoria.
  3. Buscar los datos: Acceso a la memoria.
  4. Procesarlo: Ejecución de la operación.
  5. Colocar el resultado en su sitio: Almacenamiento del resultado.

Fases de Ejecución de una Instrucción

  1. Ciclo de Captación (FETCH)

    • Fase 1: Captación de la instrucción.
    • Fase 2: Preparación de la siguiente instrucción.
    • Fase 3: Decodificación de la instrucción.

    Explicación: El Contador de Programa (PC) contiene la dirección de la instrucción a captar. El procesador copia la instrucción indicada por el PC desde la memoria y la carga en el Registro de Instrucción (RI). El PC se incrementa (a menos que se indique lo contrario), y finalmente el procesador interpreta la instrucción.

  2. Ciclo de Ejecución (EXECUTION)

    • Fase 4: Ejecución de la operación.

    Explicación: Incluye diversas acciones que se pueden combinar:

    • Procesador-Memoria: Transferencia de datos entre la CPU y la memoria.
    • Procesador-E/S: Transferencia de datos entre la CPU y un módulo de Entrada/Salida.
    • Procesamiento de Datos: Realización de operaciones aritmético-lógicas con los datos.
    • Control: Alteración de la secuencia de ejecución.

Ruptura de Secuencia de Ejecución

  1. Instrucciones de Bifurcación (Saltos):
    • Modifican el PC.
    • Permiten no ejecutar determinadas instrucciones (ej. sentencias if).
    • Permiten volver a instrucciones anteriores (ej. bucles).
  2. Interrupciones:
    • Bifurcaciones causadas por eventos externos a la CPU.

Tipos de Interrupciones

  • Programa: Causadas por eventos internos a la ejecución de un programa (ej. desbordamiento aritmético, división por cero).
  • Temporización: Generadas por un temporizador interno del procesador, permitiendo realizar funciones de forma regular.
  • E/S (Entrada/Salida): Generadas por un controlador de E/S al completar una operación o encontrar un error.
  • Fallo de Hardware: Errores detectados por el hardware (ej. error de paridad en la memoria).

Implementación de Operaciones Aritméticas

  1. Implementación Combinacional

    • Las operaciones se realizan mediante etapas en paralelo.
    • Pueden existir problemas con los retardos en el acarreo.
    • Es un método con mejor velocidad, pero también con mayor complejidad.
  2. Implementación Secuencial

    • Se realiza mediante registros de desplazamiento y etapas de suma-resta combinacional.
    • Los retardos pueden causar problemas al integrarlos en CPUs.
    • Necesitan una señal de reloj para su funcionamiento.
  3. Otras Opciones de Representación Numérica

    1. Coma Fija:
      • Necesita una ALU sencilla, se integra dentro de la CPU.
      • Requiere control de errores de precisión y corrupción de la información.
      • Puede ser utilizada como base para realizar operaciones en coma flotante por medio de software.
    2. Coma Flotante:
      • Necesita una ALU compleja.
      • Consume muchos recursos y tiempo de ejecución.
      • Se suele implementar por medio de procesadores específicos (coprocesadores) integrados dentro de la CPU.

Conceptos Clave de MIPS Assembly

Syscalls (Llamadas al Sistema)

Para interactuar con el sistema operativo, se utilizan las siguientes llamadas al sistema (se carga el código de servicio en $v0 y se llama a syscall):

  • 1: Imprimir entero
  • 4: Imprimir cadena (string)
  • 5: Leer entero
  • 8: Leer cadena (string)
  • 11: Imprimir carácter
  • 12: Leer carácter

Instrucciones de Desplazamiento

  • SLL $t0, $t1, x (Shift Left Logical): Guarda en $t0 el contenido de $t1 desplazado lógicamente x bits a la izquierda. Esto equivale a multiplicar por 2^x.
  • SRA $t0, $t1, x (Shift Right Arithmetic): Guarda en $t0 el contenido de $t1 desplazado aritméticamente x bits a la derecha. Esto equivale a dividir por 2^x, manteniendo el signo.

Nota: Para direccionamiento de memoria, un desplazamiento de 1 bit (x=1) es para bytes, 2 bits (x=2) para half-words, y 4 bits (x=4) para words.

Estructura Básica de un Programa MIPS

.data           # Sección para la declaración de variables
    # ... variables aquí ...

.text           # Sección para el código ejecutable
.globl main     # Declara 'main' como etiqueta global
main:           # Punto de entrada del programa
    # ... instrucciones aquí ...
  • Directiva .space x: Reserva x bytes contiguos en memoria.
  • Directiva .align x: Alinea la siguiente dirección de memoria a 2^x bytes.
    • .align 0: Alineación de byte (2^0 = 1 byte)
    • .align 1: Alineación de half-word (2^1 = 2 bytes)
    • .align 2: Alineación de word (2^2 = 4 bytes)
    • .align 3: Alineación de double-word (2^3 = 8 bytes)

Finalización del Programa

li $v0, 10      # Carga el código de servicio para salir del programa
syscall         # Llama al sistema para terminar

Instrucciones Condicionales (Bifurcaciones)

  • beq: Branch if equal (igual)
  • beqz: Branch if equal to zero (igual a 0)
  • blt: Branch if less than (menor que)
  • ble: Branch if less than or equal (menor o igual que)
  • bgt: Branch if greater than (mayor que)
  • bge: Branch if greater than or equal (mayor o igual que)
  • bne: Branch if not equal (distinto)
  • bnez: Branch if not equal to zero (distinto de 0)

Almacenamiento de Datos en Memoria (Endianness)

Para un array declarado como .byte (1,2,3,4):

  • La primera posición (dirección base + 0) contendrá el primer byte (1).
  • Los bytes se guardarán en memoria de izquierda a derecha en el orden en que se declaran.

Nota: Si se refiere a cómo se almacena una palabra (ej. 0x12345678) en memoria, la arquitectura MIPS es típicamente Big-Endian, lo que significa que el byte más significativo se almacena en la dirección de memoria más baja.

Entradas relacionadas: