[2011 - Marzo - Arqui 2] Ejercicio 1

[2011 - Marzo - Arqui 2] Ejercicio 1

de Martin Pacheco -
Número de respuestas: 3

Hice el ejercicio de 1 del examen de Arquitectura 2 de 2011 - Marzo [https://drive.google.com/file/d/0B61gGKV34MR5SDFOODNKRGJIb2c/view?usp=sharing].

Y aunque parto de compilar el MISMO codigo en C, tengo una solucion un poco diferente a la de las soluciones.
Mi pregunta es si mi código está correcto.
En las soluciones, veo varias diferencias:

1) Usan el registro BX para guardar la variable global, yo estoy usando una variable definida en memoria, se puede hacer de esta manera tambien?

2) El registro de segmento DS lo setean a 0 en el main, yo lo hago en la interrupcion cada vez que se invoca, supongo que esto puede hacerse indistintamente en ambos (aunque claro, es mas óptimo hacerlo en main).

3) DATAIN y DATAOUT las pasan a un registro y luego llamar a IN y OUT con ese registro, yo pongo los valores (supuse que inmediatos) en el registro, esto es igual de correcto o deberia de haberlo hecho como en la solucion?

4) No entiendo la instruccion SHL SI, 1 de la solucion (penultiuma linea de código).

5) La solucion no preserva el contexto ni en el main ni en la interrupcion, yo si lo hice "por costumbre". Si la letra no lo pide y es un sistema dedicado (y no hacerlo no perjudica el funcionamiento correcto del codigo) no nos preocupamos de preservar contexto?

El código en C de la soluciones es:

estado *s;
main {
  s = ESTADO_INICIAL;
  // instalar interrupciones
  while (true);
}

Input {
  unsigned char x = IN(DATAIN);
  OUT (DATAOUT, x & s->mask);
  s = (s->transiciones)[x];
}

Y mi código en 8086 es el siguiente:

estado db ESTADO_INICIAL
...
main:
MOV estado, ESTADO_INICIAL

;Instalo interrupciones
while:
JMP while
...
Input PROC FAR
   PUSH AX
   PUSH ES
   PUSH SI
   PUSH BX
   XOR AX, AX
   MOV ES, AX
   IN(AL, DATAIN)
   MOV SI, estado
   XOR BH, BH
   MOV BL, AL
   AND AL, ES:[SI]
   OUT(DATAOUT, AL)
   MOV estado, ES:[SI + BX + 1]
   POP BX
   POP SI
   POP ES
   POP AX
   IRET
Input ENDP
  

En respuesta a Martin Pacheco

Re: [2011 - Marzo - Arqui 2] Ejercicio 1

de Martin Pacheco -

Me auto respondo mi (duda 4):

Duda:
4) No entiendo la instruccion SHL SI, 1 de la solucion (penultiuma linea de código).

Respuesta:
"[BX+1] apunta al array de estado de 256 punteros a estado, de aquí aparece el +1 de la ezpresión [bx + si + 1]. Como estamos en intel 8086 los puntero son de dos bytes.

Queremos acceder al nuevo estado para la transición SI (x) dentro del array tenemos que movernos de a dos bytes (de a punteros), SI elementos (shl SI, 1, o sea SI*2)."

En respuesta a Martin Pacheco

Re: [2011 - Marzo - Arqui 2] Ejercicio 1

de Martin Pacheco -

Dejo link a este otro post para evitar confusiones: https://eva.fing.edu.uy/mod/forum/discuss.php?d=56840

Un puntero ocupa 2 bytes cuando es un puntero NEAR (son un offset de la direccion de memoria a la que apuntan)
Si fueran punteros FAR ocuparian 4 bytes (2 bytes de segmento, 2 bytes de offset)

En el link que puse en el mensaje de arriba, gustavo aclara eso justamente, que son 2 bytes por ser NEAR.

En respuesta a Martin Pacheco

Re: [2011 - Marzo - Arqui 2] Ejercicio 1

de Gustavo Brown -

1) Se puede, pero lo que no se puede es utilizar una instruccion con dos operandos a memoria (en tu caso el MOV estado, ES:[SI+BX+1] ). Además hay que tener cuidado con el segmento utilizado para acceder a la variable.  

3) Como no sabes el número de puerto de DATAIN/DATAOUT no podes ponerlo como inmediato porque la arquitectura 8086 solo permite para IN y OUT números de puerto menores a 256.

5) Mejor preservar el contexto

Saludos,
  Gustavo