Escribiendo el ensamblaje de MIPS y el código de máquina para obtener instrucciones

1

Continúo mi práctica con el ensamblaje de MIPS y el código de máquina. Estoy haciendo un problema que asume lo siguiente:

• variables a-j are assigned temporary registers $0-$8.
• the base address of arrays A and D are in $9 and $10.
• if need register to store an intermediate result, use remaining temporary or saved registers or register $at. 

$0 - a    $1 - b
$2 - c    $3 - d
$4 - e    $5 - f
$6 - g

Estos son los problemas:

a) f = a - 20 + b + c - d;
b) D[i] = A[j] << 6;
c) f = g - A[D[5]]

Este es mi intento:

a) addi $0, $0, 101100
   add $5, $1, $2
   add $5, $5, $0
   sub $5, $5, $3

En cuanto a b) yc), no estoy muy seguro de cómo hacerlo. He intentado encontrar ejemplos en línea, pero no he podido, y los ejemplos de los que estoy hablando no son tan buenos.

Si alguien puede verificar y ver si hay algún problema o si tiene algún consejo o ayuda, lo agradecería.

    
pregunta user655321

2 respuestas

0

A las diferentes tareas:

  • a) tu respuesta me parece correcta.

  • b) Creo que significa que los arreglos A y D se encuentran en la RAM y comienzan en las direcciones almacenadas respectivamente en $ 9 y $ 10.

    1. Primero debe tomar el valor de j y multiplicarlo por 4 (necesita un byte de compensación para la memoria: la numeración sigue a los bytes y no a las palabras, por lo que debe tomarla cuatro veces si desea jth word (32 bit) y no byte (8 bit) en la matriz!).
      - > quizás es mejor almacenar el valor directamente en un registro temporal ($ en, ...) para que no se destruya.

    2. Ahora agrega la dirección de base de memoria absoluta de la matriz (almacenada en $ 9) para tener la dirección absoluta del campo de datos al que queremos acceder.

    3. Luego tome el valor y obtenga los datos de esta dirección en la memoria. El comando para esto debe ser lw $t, offset($s) , donde $ t representa un registro temporal para almacenar los datos, $ s representa la dirección absoluta que acabamos de calcular. Aquí no necesitamos el desplazamiento, por lo que usamos 0 u omitimos completamente el valor como este: lw $t, ($s) .

    4. Este valor se debe desplazar seis veces a la izquierda: el comando es sll $d, $t, shamt , donde shamt es un inmediato, en nuestro caso el número 6.

    5. Ahora tenemos que calcular la dirección absoluta de nuestro campo de datos de destino en la matriz D (esto funciona igual que con A, solo con i en lugar de j, pero no debe usar el mismo registro donde están sus datos). se almacena, o lo sobrescribirías).

    6. Finalmente, almacene nuestro valor en la dirección correcta en la RAM con una operación muy similar a lw, sw $t, offset($s) , que funciona igual que lw (y aún no necesitamos ningún desplazamiento inmediato para agregar a nuestra dirección ).

    Permítame agregar información sobre el desplazamiento: se usa si desea acceder de forma estática a un elemento predefinido en A (que no se almacena en el registro, sino en el inmediato), por ejemplo. el cuarto. Luego usarías "lw", por ejemplo, como este: lw $at, 16($9) ..... Espera un momento: ¿Por qué 12, no queríamos el cuarto elemento? - Sí, lo hacemos, pero usar 4 nos haría leer el segundo elemento (palabra) en la matriz, que es del quinto al octavo byte.
    Recordar : la memoria está direccionada en bytes y no palabra-dirección (También puede usar esto para la tarea c), pero también puede resolverse sin él.)

  • Para c) tiene que acceder a la matriz A con una dirección relativa equivalente a los datos almacenados en la matriz D en la posición 5 (es decir, el sexto elemento). Esto debería ser realmente fácil después de la tarea b.

Espero poder aclarar algunas cosas en general, además de ayudar con este problema en particular :)

No agregué el código fuente completo porque creo que ayuda a implementar más por tu cuenta. Con estas instrucciones detalladas no debería ser demasiado difícil. Si aún tienes problemas, ¡no tengas miedo de pedir más ayuda!

Si hay errores aquí, ¡dímelo!

EDITAR: ahora, ese código real ha sido publicado. También agregaré algunos:
a)

subi $5, $0, 20 # f = a - 20
add  $5, $5, $1 # f = f - b
add  $5, $5, $2 # f = f + c
sub  $5, $5, $3 # f = f - d

b)

sll $at,  $8,   2   # at = j << 2;
add $at,  $at,  $9  # at = at + &A; (add base adress of A)
lw  $tmp, ($at)     # tmp = A[at];
sll $tmp, $tmp, 6   # tmp = tmp << 6;
sll $at,  $7,   2   # at = i << 2;
add $at,  $at,  $10 # at = at + &D; (add base adress of D)
sw  $tmp, ($at)     # D[at] = tmp;

c)

lw  $at, 20($10)     # at = D[5]; (5 * 4 bytes = 20, base address for D: $10)
sll $at, $at,    2   # at = at << 2;
add $at, $at,    $9  # at = at + &A; (add base adress of A)
lw  $at, ($at)       # at = A[at];
sub $5,  $6,     $at # f = g - at;
    
respondido por el Fabio
0

Las instrucciones dicen:

• variables a-j are assigned temporary registers $0-$8.
• the base address of arrays A and D are in $9 and $10.

Esto es confuso; si se refieren a números de registro, esto no funciona porque el primer registro es una constante 0. Si se refieren a registros temporales, es mejor, excepto que no hay $ t10. Pero voy a asumir esto último, y usaré $ s0 en lugar de $ 10 para la dirección base de D. Si esto es incorrecto, tendrá que ajustar las cosas. También usé $ s1 como temporal además de $ en.

Para b) yc), debe calcular una dirección y luego usar el direccionamiento base (utilizado por las instrucciones lw y sw) para acceder a la ubicación calculada.

Mis intentos:

a) f = a - 20 + b + c - d;

addi    $at,$a0,-20 # (no subi)   temp = a - 20
add     $at,$at,$t1 # +b          temp += b
add     $at,$at,$t2 # +c          temp += c
sub     $t5,$at,$t3 # -d          f = temp - d

que es esencialmente el mismo que el tuyo, excepto que no destruyo ningún valor original.

b) D[i] = A[j] << 6;

add $at, $t8, $t8   # temp = j * 2     (need to multiply index by 4 because 
add $at, $at, $at   # temp = temp * 2  MIPS address are 4 bytes long)
add $at, $at, $t9   # temp = &A + temp (now have address of A[j] in temp)
lw  $s1, 0($at)     # $s1 = A[j]       (get value)
sll $s1, $s1, 6     # $s1 = s1 << 6
add $at, $t7, $t7   # temp = i * 2
add $at, $at, $at   # temp = i * 2
add $at, $at, $s0   # temp = D + temp  (now have address of D[i] in temp)
sw  $s1, 0($at)     # D[i] = $s1       (store result)

c) f = g - A[D[5]];

lw  $at, 5*4($t10)  # temp = D[5]
add $at, $at, $at   # temp = D[5] * 2
add $at, $at, $at   # temp = temp * 2
add $at, $at, $t9   # temp = &A + temp (now have address of A[D[5]]
lw  $s1, 0($at)     # $s1 = A[D[5]] (get value)
sub $t5, $t6, $s1   # f = g - $s1
    
respondido por el tcrosley

Lea otras preguntas en las etiquetas