Forum Programmation.autre Problème SPARC et assembleur

Posté par  .
Étiquettes : aucune
0
19
juin
2005
Bonjour,
Je suis censé, dans le cadre d'un projet de Master1, créer une fonction appelée "uputs", capable de faire un "printf" vers un écran, qui dans mon architecture, est un TTY.
Cette architecture contient deux RAM reliées à mon processeur SPARC (l'une pour le benchmark à faire tourner, l'autre pour les données), un bus VCI et un TTY.
Si j'ai (presque) compris comment faire l'en-tete et la fin du programme, je ne vois pas du tout comment faire pour faire le corps... c'est génant :(
Faut-il juste faire un copier-coller de ce qui est dans la mémoire de donnée, et l'envoyer vers une adresse qui serait celle du TTY, ou est-ce beaucoup plus simple ?
J'ai essayé de trouver des sources pour comprendre un peu, mais meme si je connais (à peu près) l'assembleur MIPS, j'ai un gros problème de blocage sur le SPARC.
Merci beaucoup pour votre aide

PS : je ne demande évidemment pas du code tout craché, ce serait tricher :), mais juste des informations pour m'aider à comprendre.
  • # Un peu de google, oyu de recherche sur le net

    Posté par  . Évalué à 2.

    Si tu as besoin d'infos sur l'assembleur SPARC:

    A la source:
    http://docs.sun.com/app/docs?q=sparc+assembler(...)

    D'autres infos ici (pas tout vérifié):
    http://www.users.qwest.net/~eballen1/sparc.tech.links.html(...)

    Faut-il juste faire un copier-coller de ce qui est dans la mémoire de donnée, et l'envoyer vers une adresse qui serait celle du TTY, ou est-ce beaucoup plus simple ?

    C'est à dire? Ca c'est ton analyse qui doit déterminer ce qu'il faut faire. Vu le peu d'élément dont on dispose on ne peut pas t'aider.
    • [^] # Finalement, j'ai avancé

      Posté par  . Évalué à 1.

      J'ai réussi à faire un petit programme en fait très simple pour charger un texte de la RAM et le mettre sur le TTY, le voici

      .text
      .global uputs_adr
      .type uputs_adr, #function
      /*; .set noreorder */

      /* uputs_adr(adresses_physique, texte)*/

      uputs_adr:
      ldsb [ %o1 ], %o3 /*chargement du caractère pointé vers un registre local*/
      addcc %o3, 0, %o3 /*Z=0 si le caractère est \0*/
      be end_uputs_adr /*si caractère = \0, fin de chaine*/
      add %o1, 1, %o1 /* on incrémente le pointeur de caractère*/

      loop: stb %o3, [ %o0 ] /*sinon, on écrit le caractère à l'adresse du TTY*/
      ldsb [ %o1 ], %o3 /* on charge le caractère*/
      addcc %o3, 0, %o3 /*Z=0 si le caractère est \0*/
      bne loop /*si caractère != \0, on recommence*/
      add %o1, 1, %o1 /* on incrémente le pointeur de caractère*/

      end_uputs_adr:
      retl
      nop


      MAIS il n'affiche rien. Je me suis rendu compte qu'en fait, c'est parceque, dans ma simulation, je ne faisais pas de reset, c'est à dire que, lorsque le processeur demarre, il charge l'instruction reset en premier, et il fallait donc que je crée un programme assembleur pour lire le code de mon programme mis en mémoire.
      Voici donc mon code de RESET :

      .extern _stack
      .extern _gp

      .text
      .align 2

      sethi %hi(_edata), %o0
      or %o0, %lo(_edata), %o0
      sethi %hi(_edata), %o1
      or %o1, %lo(_edata), %o1
      /* mov 0, %l2 */

      sethi %hi(_stack), %sp
      or %sp, %lo(_stack), %sp
      sub %sp, 4, %sp
      sethi %hi(_gp), %g1
      or %g1, %lo(_gp), %g1

      sethi %hi(main0), %l0
      or %l0, %lo(main0), %l0
      ld [%l0 + %lo(main0)], %l0

      jmpl main0, %l0
      nop
      /* call main0
      nop */


      OR ceci ne marche pas, car gcc me renvoie ce message :

      /dsk/l1/misc/Bench/soc/cxtools/gcc_sparc/obj/bin/sparc-soclib-elf-gcc -c main.c
      /dsk/l1/misc/Bench/soc/cxtools/gcc_sparc/obj/bin/sparc-soclib-elf-as reset.s -oreset.o
      /dsk/l1/misc/Bench/soc/cxtools/gcc_sparc/obj/bin/sparc-soclib-elf-as uputs_sparc.s -o uputs_sparc.o
      /dsk/l1/misc/Bench/soc/cxtools/gcc_sparc/obj/bin/sparc-soclib-elf-ld -T./ldscript -o sparc_soft.x main.o reset.o uputs_sparc.o
      ./reset.o(.text+0x24): relocation truncated to fit: R_SPARC_13 main0
      reset.o(.text+0x24): relocation truncated to fit: R_SPARC_13 main0
      make: *** [sparc_soft.x] Error 1

      J'ai donc remplacé mon jmpl par le call en commentaire, et là ça compile, masi ça n'affiche toujours rien. Je précise que le main0 est le suivant :

      int main0(void)
      {
      uputs_adr(0xC0000000,"Salut les gens, c'est moi le SPARC\n");
      return 0;
      }

      Et là, je dois avouer que je ne vois plus du tout pourquoi ça plante...
  • # Finalement, j'ai avancé !!!

    Posté par  . Évalué à 1.

    J'ai réussi à faire le petit programme finalement très simple de prendre un message de la RAM pour la mettre sur le TTY.
    Malheureusement, si tout compile bien, rien ne s'affiche.
    J'ai trouvé pourquoi : au démarrage de la simulation, le SPARC (comme tous les ordinateurs il me semble) se met dans la position RESET et démarre.
    Or, si j'ai bien touvé un code en MIPS (c'est sur cette machine que j'ai appris à faire de l'assembleur), je n'arrive pas à le transformer...
    Enfin, presque pas : en particulier, j'ai lu la DOC du SPARC (presque) en entier (295 pages...) et je ne vois pas de registres utilisés pour l'OS (comme dans le MIPS les registres 27 et 28...
    Voici donc mon code :


    .extern _stack
    .extern _gp

    .text
    .align 2

    /* Modification de SR -> kernel avec IT */

    sethi %hi(_edata), %o0
    or %o0, %lo(_edata), %o0
    sethi %hi(_edata), %o1
    or %o1, %lo(_edata), %o1
    /* mov 0, %l2 */

    sethi %hi(_stack), %sp
    or %sp, %lo(_stack), %sp
    sub %sp, 4, %sp
    sethi %hi(_gp), %g1
    or %g1, %lo(_gp), %g1

    sethi %hi(main0), %l0
    or %l0, %lo(main0), %l0
    /* ld [%l0 + %lo(main0)], %l0 */

    jmpl main0, %l0
    nop
    /* call main0
    nop */



    Voici ce que gcc, en utilisant l'option du SPARC bien éidemment :) me répond :

    /dsk/l1/misc/Bench/soc/cxtools/gcc_sparc/obj/bin/sparc-soclib-elf-gcc -c main.c
    /dsk/l1/misc/Bench/soc/cxtools/gcc_sparc/obj/bin/sparc-soclib-elf-as reset.s -oreset.o
    /dsk/l1/misc/Bench/soc/cxtools/gcc_sparc/obj/bin/sparc-soclib-elf-as uputs_sparc.s -o uputs_sparc.o
    /dsk/l1/misc/Bench/soc/cxtools/gcc_sparc/obj/bin/sparc-soclib-elf-ld -T./ldscript -o sparc_soft.x main.o reset.o uputs_sparc.o
    ./reset.o(.text+0x2c): relocation truncated to fit: R_SPARC_13 main0
    reset.o(.text+0x2c): relocation truncated to fit: R_SPARC_13 main0
    make: *** [sparc_soft.x] Error 1

    J'ai donc remplacé le jmpl par le call (en commentaire sur cette version...) et ça compile... mais ça n'affiche rien ...
    Voici donc mes questions :
    1°) Pourquoi ce message d'erreur ?
    2°) Comment faire pour le corriger car je pense que CALL n'est pas une bonne solution.


    PS : Le principe de ce RESET est de mettre main0 en mémoire pour démarrer. Le main0 doit juste faire la commande d'affiche uputs que voici :

    .text
    .global uputs_adr
    .type uputs_adr, #function
    /*; .set noreorder */

    /* uputs_adr(adresses_physique, texte)*/

    uputs_adr:
    ldsb [ %o1 ], %o3 /*chargement du caractère pointé vers un registre local*/
    addcc %o3, 0, %o3 /*Z=0 si le caractère est \0*/
    be end_uputs_adr /*si caractère = \0, fin de chaine*/
    add %o1, 1, %o1 /* on incrémente le pointeur de caractère*/

    loop: stb %o3, [ %o0 ] /*sinon, on écrit le caractère à l'adresse du TTY*/
    ldsb [ %o1 ], %o3 /* on charge le caractère*/
    addcc %o3, 0, %o3 /*Z=0 si le caractère est \0*/
    bne loop /*si caractère != \0, on recommence*/
    add %o1, 1, %o1 /* on incrémente le pointeur de caractère*/

    end_uputs_adr:
    retl
    nop

    Et voici le main0 pour que, j'espère, ce soit plus clair :

    /* #define TTY_BASE 0xC0000000 */

    int main0(void)
    {
    uputs_adr(0xC0000000,"Salut les gens, c'est moi le SPARC\n"); /* 0xC0000000 est l'adresse de mon TTY suivant mon architecture.*/
    return 0;
    }

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.