Vous êtes sur la page 1sur 6

TP3 Exemple de jeu dinstruction du processeur C6x

Manipulation N1 : appel dune fonction en assembleur partir dun programme en C

Calcul de la somme de n + (n - 1) + (n - 2) + . . . + 1 Cet exemple illustre la possibilit dexcuter une fonction crite en assembleur partir dun programme en C. Le programme sum.c fait appel la fonction sumfunc.asm
//sum.c - calcul de la somme n+(n-1)+...+1. Appel de la fonction sumfunc.asm #include <stdio.h> main() { short n=6; short resultat; resultat = sumfunc(n); //appel de la fonction en assembleur sumfunc printf(somme = %d, resultat);

}
;sumfunc.asm fonction assembleur pour la calcul de n+(n-1)+...+1 .def _sumfunc _sumfunc: MV .L1 SUB .S1 LOOP: [A1] ADD SUB B NOP B NOP .end .L1 .S1 .S2 .S2 A4,A1 A1,1,A1 A4,A1,A4 A1,1,A1 LOOP 5 B3 5 ;fonction appele depuis le prog. en C ;compteur (n) dans A1 ;dcrmentation de n ;addition et accumulation dans A4 ;dcrmentation du compteur ;branchement LOOP si A1#0 ;5 NOPs pour le dlai associ B ;retour la routine dappel (C) ;5 NOPs pour le dlai associ B

Dans le programme sumfunc.asm la valeur de n, spcifie dans le programme en C, est passe au programme assembleur laide du registre A4 (par convention). Pour faire passer plus de valeurs il est possible dutiliser dautres registres A4, B4, A6, . Le nom de la fonction est prcd par le symbole _ par convention (seulement si la fonction est appele partir dun programme en C). La valeur de n, place dans le registre A4, est ensuite dplace dans le registre A1 (Instruction MV, A1 jouera le rle du compteur). Le registre A1 est ensuite dcrment (SUB). La boucle du programme commence avec le label (ou adresse) LOOP et

termine avec la premire instruction de branchement B. Cette boucle inclut deux instructions, ADD pour le calcul de la somme et SUB pour la dcrmentation du compteur. La condition de branchement sur la boucle ne se fait que si la donne dans le registre A1 est diffrentes de zro ([A1] B). A noter que seuls les registres A1, A2, B0, B1 et B2 peuvent tre utiliss comme registre conditionnel. La seconde instruction de branchement sert au retour ladresse B3 (par convention) du programme en C. Le rsultat de la somme est contenu dans le registre A4 et est pass la variable resultat du programme C. Les 5 NOPs (no operation) suivent les deux instructions de branchement et permettent dinsrer 5 dlais associ cette instruction. Les units .S et .L slectionnes sont donnes titre indicatif mais ne sont pas ncessaires dans ce programme (elles peuvent tre utilises pour le dbogage du programme). Compiler et excuter le programme Ajouter aux deux fichiers prcdents les fichiers suivants o csl6713.lib o dsk6713bsl.lib o rts6700.lib o c6713dsk.cmd (dossier support) utiliser les options de compilation standards

Calcul du factoriel de n Les deux programmes factoriel.c et factfunc.asm calculent le factoriel dun nombre n
//factoriel.c : calcul du factoriel de n. appel de la fonction factfunc.asm #include <stdio.h> //pour laffichage void main() { short n=7; short resultat; resultat = factfunc(n); // appel de la fonction en assembleur sumfunc factfunc printf(factoriel = %d, resultat); }

;factfunc.asm .def _factfunc: MV SUB LOOP: MPY NOP SUB B

fonction assembleur appele depuis le programme C _factfunc ;fonction asm appele depuis le prog. C A4,A1 ;compteur (n) dans A1 A1,1,A1 ; dcrmentation de n A4,A1,A4 A1,1,A1 LOOP ;produit et accumulation dans A4 ;(A4xA1->A4) ;dlai de 1 associ avec MPY ;dcrmentation du compteur ;branchement LOOP si A1#0

[A1]

Page 2 sur 6

NOP 5 B B3 NOP 5 .end

;5 NOPs pour le dlai associ B ;retour la routine dappel (C) ;5 NOPs pour le dlai associ B

Tester le programme. Utiliser les mmes indications que pour le premier exemple (fichiers ajouter et options de compilation)

Programme assembleur appelant un autre programme assembleur Le projet suivant permet de calculer la somme de produit de deux vecteurs x,y (ici x=[1 2 3 4] et y=[0 2 4 6] soit 1*0 + 2*2 + 3*4 + 4*6 = 40)
;sommeproduit_init.asm - programme ASM pour linitialisation des ;des variables. Appel le fichier spfunc.asm .def .ref .text x_addr .short y_addr .short result_addr .short init MVK MVKH MVK STH MVK MVK MVKH MVK B MVK MVKH NOP MVK MVKH STW B NOP init spfunc 1,2,3,4 0,2,4,6 0 ;adresse de dbut ;fonction ASM appele ;rserve une section de la mmoire pour ;le code ;valeurs pour le vecteur x ;valeurs pour le vecteur y ;initialise le rsultat ;A4 = lower 16-bit addr -->A4 ;A4 = higher 16-bit addr-->A4 ;A3 = 0 ;initialise le rsultat 0 ;A4 = 16 LSBs adresse de x ;B4 = 16 LSBs adresse de y ;B4 = 16 MSBs adresse de y ;A6 = taille des vecteurs ;branchement la fonction spfunc ;B3 = adresse retourne depuis spfunc ;B3 = adresse retourne depuis spfunc ;3 dlais (aprs branchement) ;A0 = 16 LSBs result_addr ;A0 = 16 MSBs result_addr ;store result ;pause ;dlai associ linstruction de ;branchement

result_addr,A4 result_addr,A4 0,A3 A3,*A4 x_addr,A4 y_addr,B4 y_addr,B4 4,A6 spfunc ret_addr,B3 ret_addr,B3 3 result_addr,A0 result_addr,A0 A4,*A0 wait 5

ret_addr wait

;spfunc.asm Multiplication de deux vecteurs. Appele depuis ;sommeproduit_init.asm ;A4=adresse de x, B4=adresse de y, A6=conteur(taille des vecteurs) ;B3=adresse retourne

Page 3 sur 6

.def .text spfunc loop MV ZERO LDH LDH NOP MPY NOP ADD SUB B NOP MV B NOP

spfunc

A6,A1 A7 *A4++,A2 *B4++,B2 4 A2,B2,A3 A3,A7,A7 A1,1,A1 loop 5 A7,A4 B3 5

[A1]

;la fonction somme des produits ;inclus le code suivant dans la section ;text (cest une directive pour le ; compilateur) ;move compteur de boucle --> A1 ;init A7 pour laccumulation ;A2=adresse de x ;B2=adresse de y ;4 dlais pour LDH ;A3 = x * y ;1 dlai pour MPY ;somme des produits dans A7 ;dcrmentation du compteur ;branchement loop si A1#0 ;5 delais pour B ;A4=resultat ;retour ladresse dans B3 (ret_addr) ;5 delais pour B

;vectors_sp.asm fichier Vector pour le projet sommeproduit .ref rst: .sect mvkl .s2 mvkh .s2 b nop init vectors init,b0 init,b0 b0 5 ;adresse de dbut dans le fichier ;dinitialisation ;in section vectors ;init addr 16 LSB >B0 ;init addr 16 MSB >B0 ;branchement addr init

Crer un projet et ajoutez-y : Les trois fichiers asm (sommeproduit_init.asm ; spfunc.asm et vectors_sp.asm Le fichier c6713dsk.cmd (dossier support) Au niveau des options de compilation seule loption suivante du linker doit tre change (pour ne pas avoir un warning) Linker Basic Autoinit Model : No Autoinitialization Compilez et testez le programme Analyse du programme Le programme assembleur sommeproduit_init.asm initialise les valeurs des vecteurs x et y et fait appel la fonction assembleur spfunc.asm , les adresses des vecteur x et y (x_addr et y_addr) ainsi que la taille des vecteurs sont envoys cette fonction grce aux registres A4, B4 et A6. La fonction spfunc calcul la somme des produits de x et y et retourne ladresse indique dans le registre B3 (ce registre contient ladresse de ret_addr ). Le rsultat du calcul (40) est stock dans un premier temps dans le registre A4 puis la valeur est enregistre dans la case mmoire indique par result_addr. Page 4 sur 6

Le programme vectors_sp.asm envoie ladresse du dbut de programme (ladresse init du programme sommeproduit_init.asm), ceci se fait avec la commande de branchement b comme indiqu ci-dessous :
mvkl .s2 mvkh .s2 b init,b0 init,b0 b0

Pour un fonctionnement correcte le code du programme vectors_sp.asm doit tre plac en dbut de la mmoire. La directive .sect indique justement o la fonction rst doit tre place, lindication est dans loprande de cette directive, soit le terme vectors . Le quatrime fichier de notre projet est le fichier C6713dsk.cmd, ce fichier comporte en fait des directives (MEMORY et SECTIONS (en majuscule)) au compilateur lui indiquant les plages mmoire disponibles. En retrouve dans ce fichier le terme vectors qui fait rfrence la plage mmoire IVECS (adresse de dbut 0h et de longueur 220 octets)
/*C6713dsk.cmd Linker command file*/ MEMORY { IVECS: IRAM: SDRAM: FLASH: } SECTIONS { .EXT_RAM .vectors .text .bss .cinit .stack .sysmem .const .switch .far .cio .csldata }

org org org org

= = = =

0h, 0x00000220, 0x80000000, 0x90000000,

len len len len

= = = =

0x220 0x0002FDE0 0x01000000 0x00020000

:> :> :> :> :> :> :> :> :> :> :> :>

SDRAM IVECS IRAM IRAM IRAM IRAM IRAM IRAM IRAM IRAM IRAM IRAM

Finalement la ligne,
.sect vectors

indique tout simplement au compilateur (cest une directive) que le code qui vient aprs, soit :
rst: mvkl .s2 init,b0

Page 5 sur 6

mvkh .s2 b nop

init,b0 b0 5

doit tre plac en dbut de mmoire de sorte qu lexcution (lecture du code partir de ladresse 0h) le branchement init ce fait. Comme le programme naffiche aucun rsultat (pas dinstruction printf !) il est ncessaire de vrifier le bon fonctionnement de notre programme directement en lisant les valeurs dans les registres et les cases mmoire utilises. Pour ce faire, procd comme suit : 1. Visualisation des valeurs des diffrents registres a. Allez au menu View puis Registers puis slectionnez Core Registers b. Sinon cliquez sur licne Register Window ( gauche) Visualisation des adresses mmoires utilises a. Allez au menu View puis Memory b. Dans la fentre qui apparat (Memory Window Options) i. Indiquez dans le champ Title la fonction spfunc ii. Pour Format : choisissez 16-Bit Signed Int Vous pouvez visualiser le code assembleur gnr par le compilateur en : a. Cliquant sur licne View disassembly b. Ou bien partir du menu View puis Disassembly

2.

3.

Analysez les valeurs des diffrents registres ainsi que les donnes (et programmes) de la mmoire utilise. Visualisez le code gnr et vrifiez que le code :
rst: mvkl .s2 init,b0

est mis ladresse de dbut de mmoire 0000 0000 , avec la valeur de init = 0000 0234 qui correspond ladresse de linstruction :
init MVK result_addr,A4

Exercice Concevez un programme en C qui fait appel une fonction en assembleur pour le calcul du terme [a2 + (a+1)2 + (a+2)2 + + (2a-1)2] [b2 + (b+1)2 + (b+2)2 + + (2b-1)2]. Le programme en C doit passer les valeurs de a et b au sous programme et afficher le rsultat.

Page 6 sur 6