Las instrucciones SW y LW se definen como:
sw $t, offset($s) : 1010 11ss ssst tttt iiii iiii iiii iiii
lw $t, offset($s) : 1000 11ss ssst tttt iiii iiii iiii iiii
SW realiza la operación MEM[$s + offset] = $t, pero en la ruta de datos parece que han realizado la operación MEM[Data($s)+ offset] = $t, porque en lugar de tomar el valor $ s como entrada en la ALU tomó los datos almacenados en $s.
LW realiza la operación $t = MEM[$s + offset], pero mirando la ruta de datos parece que está realizando $t = MEM[Data($s) + offset].
Otra cosa que no entiendo es por qué usamos extender el signo en lugar de simplemente mover el signo al bit 32 y llenar el resto de los datos con ceros. Si ha definido un desplazamiento es
0x8fff: 1000 1111 1111 1111
será un signo extendido a 0xffff8fff: 1111 1111 1111 1111 1000 1111 1111 1111, que es un número completamente diferente del desplazamiento, el número que realmente necesitamos es 0x80008ffff.
$s
y $t
son especificadores de registro. Su interpretación MEM[RegisterData(s) + offset]
es básicamente correcta. $s
significa, esencialmente, "obtener los datos del número de registro s
en el archivo de registro". Entonces, si s
en la instrucción está el patrón de bits 10001
, entonces $s
significa: lea el valor del registro 17, agregue los bits de compensación de signo extendido (los 16 bits representados por en i
la codificación) y utilícelos como la dirección para acceder a la memoria. Del mismo modo para el $t
en la lw
instrucción. Significa volver a escribir los datos en el registro numerado t
.
Su pregunta sobre la extensión del signo: busque el complemento a dos . El número de complemento a dos de 16 bits 0000 1111 1111 1111 es decimal +4095. El número de complemento a dos de 16 bits 1000 1111 1111 1111 es decimal -28673. El número de complemento a dos de 32 bits 0xffff8fff también es -28673. El número de complemento a dos de 32 bits 0x80008fff es decimal -2147446785, que claramente no es lo que desea.