Buen día!
Este ejercicio es un poco extraño porque no existen instrucciones que accedan a memoria (las típicas LOAD y STORE) de otros sets de instrucciones. En lugar de eso, el acceso a memoria se realiza a través de la entrada/salida, utilizando las instrucciones IN y OUT de una manera especial. Las instrucciones IN y OUT son similares en concepto a las LOAD y STORE. IN recibe como parámetro una dirección en la cual leer (a la que llamamos 'puerto de E/S'), mientras que OUT recibe una dirección donde escribir y un valor a escribir. La diferencia está en que si bien LOAD y STORE leen y escriben desde memoria, IN y OUT lo realizan sobre el espacio de entrada/salida, es decir, interactúan con otros dispositivos de E/S que se conectan a la CPU, cada uno de los cuales tiene una dirección diferente.
En este ejercicio se asume que hay algún dispositivo que oficia de interfaz con la memoria, y que tiene un protocolo especial de comunicación. Para leer de memoria, hay que pasarle al dispositivo la dirección que se desea leer y el dispositivo va a devolver el valor leído en otro puerto. Básicamente se divide el acceso a memoria en dos partes: indicarle la dirección al dispositivo y obtener el resultado. La dirección que se desea leer se indica en el puerto LEER_MEM_1, la cual es una constante, podríamos haber puesto un número en específico (0x4444, por decir algo), pero elegimos la constante para que el código sea más legible. Una vez realizado el OUT, lo que nos podemos imaginar es que el dispositivo recibe la dirección en cuestión, interactúa con la memoria, lee en la dirección que le indicamos y guarda el contenido de memoria en el registro de E/S accesible en la dirección LEER_MEM_2 (que también es una constante). De esta forma, ahora sí, cuando la CPU ejecute la instrucción IN en la dirección LEER_MEM_2, va a leer el valor de memoria que se solicitó.
El proceso de escritura es similar, si entendiste la parte anterior te propongo que trates de entenderlo del mismo dudo, si persisten las dudas por favor volvé a preguntar!
------------------------------------------------------------------------
Con respecto a la memoria, lo más normal es que la memoria sea direccionable de a bytes, eso quiere decir que cada byte de la memoria se puede acceder a través de una dirección diferente. El modelo mental que al menos yo me hago para este caso, es imaginar la memoria como un arreglo, donde cada posición del arreglo es de solo un byte (similar a como dijiste tú de que la memoria almacena palabras de a un byte). La memoria no funciona exactamente así, pero es un modelo que ayuda a imaginarnos lo que pasa.
La alternativa a la memoria direccionable de a bytes sería que la memoria sea direccionable de a palabras. Cada dirección de memoria se asocia a una palabra de memoria diferente (de un cierto tamaño, pero que coincide con el ancho de los registros y bus de datos). En este caso, si la palabra fuera de 16 bits, y accedemos a la dirección 0x0000, la memoria nos va a devolver 16 bits, mientras que si accedemos a la dirección 0x0001, nos va a devolver 16 bits diferentes. Mentalmente me lo imagino como un arreglo donde cada posición del arreglo tiene 16 bits.
En el ejercicio 1 no se indica, pero se asume que hay direccionamiento de a bytes (es lo más normal), en el ejercicio 3 podés deducir que el direccionamiento es de a palabra, como decís vos, porque te dice que hay 100 palabras entre las direcciones 101h y 165h, lo cual da 100 lugares en decimal. De ahí se deduce que cada dirección se mapea con 16 bits diferentes. En el ejercicio 4 se puede realizar el mismo razonamiento, pero en este caso la palabra de memoria es de 32 bits, porque al inicio se indica que la arquitectura es de 32 bits.
Avisame si se entiende o si conviene que aclare algo!
Saludos,
Federico