Programación en lenguaje ensamblador para el RISC-V. (Estudio del set de instrucciones)

in #spanish4 years ago

   Soy estudiante de ingeniería electrónica de la Universidad Simón Bolívar de Venezuela (USB), hace unos meses me encontraba cursando la materia “Arquitectura del computador 2” donde se nos estuvo evaluando la elaboración de programas en lenguaje “Assembler” a través del rars. En esta ocasión se nos hizo entrega de un código para ser simulado en el simulador “openDLX” y estudiar su funcionamiento.

  Objetivos:

  Estudiar el set de instrucciones RISC-V, y simular la ejecución de un programa escrito en lenguaje ensamblador. Se nos izo entrega de un código en lenguaje ensamblador, el cual presentaba cierto inconveniente y había que encontrarlo para poder solucionarlo y que realizara su función sin ningún problema.

  Implementación y desarrollo :

  El código en ensamblador que se usó suma los elementos de un arreglo y coloca el resultado final en un registro. Al ejecutar el código ocurren ciertos problemas que hacen que el resultado no sea el esperado (0x37).

  Problemas en las instrucciones de salto:

  El código en “assembler” se queda atascado en la sección de “loop” porque no se ejecuta la instrucción (j loop) sino hasta que llega a instrucciones de otros “labels” que no debería ejecutar. IF cae en la instrucción de jump, luego ID lo reconoce como” jump “pero para este momento IF ya está leyendo la siguiente instrucción de abajo (add r11, r0, r0). Ninguna instrucción de abajo salta a el label “Loop” y sin embargo llega hasta (bnez r12, end_for) y luego es que salta a el principio del label “Loop”. Esto también ocurre para el label “For” ya que se vuelve a llamar a sí misma solo que como la situación anterior el instrucción fetch sigue corriendo y llega a la instrucción de terminar el programa en el label “end_for”.

  Problemas en las instrucciones de "load word":

  Cuando se ejecutan las instrucciones de "load word" antes de una suma la cual involucra el registro al que se le está insertando un dato, ocurre un problema ya que cuando ID está en la instrucción de suma esta usa los datos del registro usado para load word, solo que todavía no ha sido cargado uno dato para el registro y por lo tanto la suma da un resultado equivocado.

  Problemas en las instrucciones de suma:

  Si la instrucción de suma esta antes de una instrucción tipo store word ocurre un problema ya que por ID el registro todavía no ha sido modificado por la suma entonces lo que se almacena en la instrucción de "store word" es equivocado.

  Problemas de instrucciones de condición :

  Cuando se cumple una condición, el IF sigue corriendo y ejecuta otras opciones antes de que haga el salto. En el código ocurre que ignora el salto sino hasta que se llama otra vez al "label". Esto resulta en problemas luego con datos del registro o otras instrucciones.

  Solución al código :

  Ya que existen problemas por causa de cómo van pasando las etapas del pipeline por cada instrucción, se planteó la solución de generar retardos al pipeline por medio de instrucciones que no aportan nada al código ni a su resultado (add r0,r0,r0), pero ayuda a que el pipeline se retrase para que no ejecute instrucciones que no debería en un momento dado. Para las instrucciones de salto se puede ver de la figura que con el retraso del pipeline esta nunca llega al “label end_loop” que era lo que estaba haciendo inicialmente.


Cause segmentado. (Imagen propia)

  Esto también ocurre para el label “for_loop” y al utilizar las mismas instrucciones se genera el retraso que hace que no se vaya a el “label” que termina el programa.

  Para instrucciones que dependen de una instrucción de suma anterior, primero tiene que ocurrir un retraso en la instrucción de suma para no escribir un valor que no es en la instrucción dependiente.


Imagen propia

  Podemos ver que si ponemos el retraso le da tiempo al “addi” almacenar el valor correcto para luego ser guardado con “store Word”. De no haberse implementado eso, se hubiera almacenado un valor diferente al resultado de la suma.

  Lo mismo ocurre para instrucciones tipo “Branch”. Si hacemos un retraso a la condición una vez que se sabe que se cumple, podrá hacer el salto. De no ser así, el pipeline simplemente ignora el salto y comienza a ejecutar instrucciones que se supone que no debería ejecutar, afectando el resultado del código.


Imagen propia

  De la imagen podemos ver que para cuando WB este en bnez, ya r12 estará en 1 y se ejecutará el salto. De no ser asi, el IF simplemente sigue a la siguiente instrucción.

  Por último tenemos a las instrucciones tipo lw y sw. Al igual que las otras, estas necesitan un retraso del pipeline para establecer bien que datos cargaran (lw) y que datos almacenarán (sw).


Imagen propia

  Vemos que si no tuviéramos el retraso, simplemente el registro r1 tuviera un valor diferente gracias al ID. al usar el retraso le damos chance al la instrucción de add de usar el valor correcto en r1 ya que este ya que lw ya está en WB.

  Al usar todos estos retrasos tenemos como resultado:


Imagen propia.

  Esto es el resultado esperado del código.

  Conclusiones

  Al implementar esta solución al problema se logró obtener el resultado esperado con una cantidad mayor de ciclos al código original. Sin embargo, este método permite que haya .un control sobre el pipeline que permite ejecutar instrucciones en el momento indicado.

  Referencias:

  Terrones Angel, código "A2", entregado en noviembre de 2019

Sort:  



¿Existe la maldición generacional en la familia?, Comenta lo que entiendes de nuestro Publicación del tema.
Mira nuestra Discord
Sigue mi cuenta oficial en @hiroyamagishi

Congratulations @orbital753! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You received more than 6000 upvotes. Your next target is to reach 7000 upvotes.

You can view your badges on your Steem Board and compare to others on the Steem Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Vote for @Steemitboard as a witness to get one more award and increased upvotes!


This post has been voted on by the SteemSTEM curation team and voting trail. It is elligible for support from @curie and @minnowbooster.

If you appreciate the work we are doing, then consider supporting our witness @stem.witness. Additional witness support to the curie witness would be appreciated as well.

For additional information please join us on the SteemSTEM discord and to get to know the rest of the community!

Please consider using the steemstem.io app and/or including @steemstem in the list of beneficiaries of this post. This could yield a stronger support from SteemSTEM.

Coin Marketplace

STEEM 0.30
TRX 0.12
JST 0.034
BTC 63960.62
ETH 3142.95
USDT 1.00
SBD 3.95