¿Cuál es la forma más sencilla de iterar a través de una matriz de ensamblaje mips?

CorePress2024-01-24  10

Esta pregunta ya tiene respuestas aquí: Almacenar un valor en cada elemento de una matriz: convertir un bucle C do{} while en MIPS asm

(1 respuesta)

Traducir la función C con argumentos a MIPS: recorrer una matriz int y contar los negativos

(2 respuestas)

Lenguaje ensamblador MIPS atravesando una matriz

(1 respuesta)

¿Recorriendo la matriz usando el bucle while? - MIPS [duplicado]

(1 respuesta)

Cerrado

hace 2 años

.

Quiero replicar esto de la manera más limpia posible

En Python

A = [0,0,0,0,0]
i = 0
while(i != 5):
    A[i] = 10
    i++

Es decir, quiero iterar a través de una matriz y establecer todos sus valores en [10,10,10,10,10]

Esto es lo que he hecho en el ensamblaje de mips

.data 
    array:  .word   0:5
    
.text
    
main:
    li $t1, 0       # i = 0
    la $t9, array       # $t9 = addr(array)
    li $t8, 10      # $t8 = 10
    

    
start_loop:
    beq $t1, 5, end_loop # if i == 5 jump to end loop
    
    sll $t2, $t1, 2     # $t2 = i x 4
    add $t2, $t9, $t2   # $t3 = addr(array[i])
    sw $t8, 0($t2)      # array[i] = $t8
    addi $t1, $t1, 1    # i = i + 1
    j start_loop

end_loop:

    li $v0, 10    # end program
    syscall

Siento que uséTantos registros y esta no es la forma más limpia de hacerlo. Cualquier ayuda se agradece

(También me aseguro de usar un bucle. Podría codificar esto sin un bucle, pero solo estoy tratando de encontrar otras formas de usar bucles)

La versión final totalmente optimizada en la respuesta de Craig sobre la traducción de la función C con argumentos a MIPS: recorrer una matriz int y contar los negativos es lo que debería estar haciendo. Dentro del bucle, solo hay 3 instrucciones para su caso: sw / addiu puntero incrementado en 4 / bne $p, $endp, top_of_loop (donde endp es un puntero a 1 después del final y(Ya calculaste antes, antes del ciclo). Como no lo necesitas dentro del bucle, optimízalo.

-Peter Cordes

27/03/2021 a las 13:28



------------------------------------

.data 
    array:  .word   0:5
    array_end:
.text
    
main:
    la     $t2, array
    addiu  $t1, $t2, 20   # one-past-end address for loop condition
                 # or  la $t1, array_end  to avoid hard-coding length
    li     $v0, 10

start_loop:                  # do{
    sw     $v0, 0($t2)          # array[i] = $t8
    addiu  $t2,$t2,4            #increment pointer after
   beq $t1, $t2, start_loop  # }while(p != endp);

#end_loop:
    #li $v0, 10         # exit call number happens to be the same value we wanted to store
    syscall             # exit

Alteraciones (con ayuda de Peter)

Así que lo primero que se hizo fue eliminar la variable i. En lugar de eso, podemos comparar la dirección de $t2, el puntero a la matriz, con el puntero final que configuramos fuera del bucle ($t1), eso nos dirá que hemos terminado. Ramificando al start_loop si no.

Los incrementos del puntero en lugar de rehacer la indexación cada vez son especialmente buenos en máquinas como MIPS que no tienen modos de direccionamiento indexados.

Bucleg con la rama condicional en la parte inferior del bucle significa que no necesita una instrucción j y es idiomático para el lenguaje ensamblador en todos (?) ISA (por ejemplo, ¿por qué los bucles siempre se compilan en el estilo "hacer...mientras" ( salto de cola)?). Es especialmente bueno cuando sabes que el bucle definitivamente se ejecutará al menos una vez, por lo que no necesitas una rama delante del bucle para tal vez omitirlo.

Respondido

27 de marzo de 2021 a las 12:30

Cansado pero despierto

Cansado pero despierto

157

1

1 insignia de plata

9

9 insignias de bronce

5

Eso es una mejora, pero no es necesario dentro del bucle, por lo que puedes guardar instrucciones en el bucle simplemente incrementando el puntero. (Con bne $t1, $t2, start_loop en la parte inferior como rama del bucle). Consulte los duplicados vinculados de esta pregunta para obtener mejores ejemplos. Tenga en cuenta que beq $t1, 5 necesita un registro temporal interno para cargar un 5, por lo que en realidad es bastante ineficiente. Si fuera a utilizar un registro de contador separado, agregaría $t1, $t1, -1 / bnez $t1, start_loop en la parte inferior.

-Peter Cordes

27/03/2021 a las 13:51

Sí, esa es la idea correcta, pero aún necesitas iniciar t2 en el puntero inicial. Así que también puedes hacer $t2, array / addiu $t1, $t2, 20. (O pegar una etiqueta al final de la matriz y $t1, array_end, para no tener que esforzarte). codifica el tamaño en cualquier lugar, aunque el ensamblador integrado limitado de MARS no te permitirá hacer cosas como .equ arrlen, . - array para que calcule una longitud por ti).

-Peter Cordes

28 de marzo de 2021 a las 0:24

Además, optimización divertida: podrías usar $v0 para retener 10, por lo que necesitarás retener un 10 más tarde para la llamada al sistema de salida.

-Peter Cordes

28 de marzo de 2021 a las 0:26

@PeterCordes gracias por esto una vez más. Apreciado.

- Cansado pero despierto

28 de marzo de 2021 a las 0:35

Edité tu conjunto por estilo, p. quitar cComentarios que no añaden nada y ordenan la sangría. También se agregó alguna explicación más. Por supuesto, siéntete libre de editar todo esto con tus propias palabras; es tu respuesta y esta es solo mi sugerencia.

-Peter Cordes

28 de marzo de 2021 a las 0:43



------------------------------------

  .data
  array: .word 0:5

  .text
  main:
  li $t1, 0     #initialize i = 0
  la $t2, array #load address of array[0]
  li $t3, 10    #save 10 in a register 

  loop:
  beq $t1, 5, end       #if i == 5, end
  sw $t3, ($t2)     #array[i] = 10

  add $t2, $t2, 4   #increment array address pointer by 4
  add $t1, $t1, 1       #i = i + 1

  j loop


  end:
  li $v0, 10
  syscall
Compartir Seguir editado

27 de marzo de 2021 a las 12:38

Respondido

27 de marzo de 2021 a las 12:31 p.m.

falso

falso

1

1

1 insignia de bronce

randomThread
ios: no se puede establecer el color del texto de UILabel implementado como vista personalizada para UIBarButtonItemPython: ¿encuentra un elemento en la lista que aparece al menos el 60% del tiempo usando el enfoque Divide y vencerás?javascript - Conversión de objeto en matriz utilizando funciones de ES6dart - Flutter: no se pueden cargar datos específicos desde la APIhtml: tengo problemas para alinear