Vous êtes sur la page 1sur 3

Architecture des ordinateurs et systmes dexploitation Corrig du TD 6: Des structures de contrle du langage C vers lassembleur

Marcel Bosc Christophe Dehlinger Benot Meister Arnaud Giersch Nicolas Passat Mathieu Haefele

1. If-then-else Traduire le programme C suivant en assembleur S PARC :


# i n c l u d e < s t d i o . h> i n t main ( v o i d ) { int a , b ; a = 5; s c a n f ( "%d" , &b ) ; if (a < b) p r i n t f ( "c est plus petit \n" ) ; else p r i n t f ( "c est plus grand \n" ) ; return 0; }

Correction :
! --- donnees --.section ".rodata" .align 1 .SCANF0: .asciz "%d" .PRINTF0: .asciz "cest plus petit\n" .PRINTF1: .asciz "cest plus grand\n" ! --- instructions --.section ".text" .align 4 .global main main: save %sp, -96, %sp set 5, %l0 set .SCANF0, %o0 add %fp, -4, %o1 call scanf nop ! ! ! ! ! ! rserve un cadre de pile de 96 octets l0 = 5 premier argument pour scanf = SCANF0 deuxieme argument pour scanf = [fp-4] appel de scanf, qui stocke donc la variable lue dans [fp-4] ld [%fp-4], %l1 cmp %l0, %l1 bge .PLUS_GRAND nop set .PRINTF0, %o0 call printf nop ba .FIN nop .PLUS_GRAND: set .PRINTF1, %o0 call printf nop .FIN: clr %i0 ret restore ! recupre le rsultat de scanf ! compare l0 avec l1 ! si l0 > l1 va au label PLUS_GRAND

! appel du printf !

! evite la partie .PLUS_GRAND

! appel du printf ! ! un nop apres tout branch ou call

2. Boucle while Traduire le programme C suivant en assembleur S PARC :


# i n c l u d e < s t d i o . h> i n t main ( v o i d ) { int a , b ; a = 0; s c a n f ( "%d" , &b ) ;

w h i l e ( a <= b ) { p r i n t f ( "%d\n" , a ) ; a ++; } return 0; }

Correction :
! --- donnees --.section ".rodata" .align 1 .SCANF0: .asciz "%d" .PRINTF0: .asciz "%d\n" ! --- instructions --.section ".text" .align 4 .global main main: save %sp, -96, %sp mov %g0, %l0 set .SCANF0, %o0 add %fp, -4, %o1 ! rserve un cadre de pile de 96 octets ! l0 = 0 ! appel de scanf ! .FIN: clr %i0 ret restore call scanf nop ld [%fp-4], %l1 .WHILE: cmp %l0, %l1 bg .FIN nop set .PRINTF0, %o0 mov %l0, %o1 call printf nop add %l0, 1, %l0 ba .WHILE nop ! compare les valeurs ! si l0 > l1, ne rentre pas dans la boucle ! affiche la valeur de l0 ! ! rcupre le rsultat du scanf

! incrmente l0 ! retourne au dbut de boucle

3. Fonction rcursive (i) crire une fonction rcursive en C qui partir de deux entiers positifs x et y calcule xy . Correction :
# i n c l u d e < s t d i o . h> int puissance ( int n , int puiss ) { i f ( puiss > 0) return n ( puissance ( n , puiss 1)); else return 1; } i n t main ( v o i d ) { int x , y ; s c a n f ( "%d" , &x ) ; s c a n f ( "%d" , &y ) ; p r i n t f ( "x^y = %d\n" , p u i s s a n c e ( x , y ) ) ; return 0; }

(ii) Traduire cette fonction en assembleur S PARC. Correction :


! --- instructions --.section ".text" .align 4 .global puissance puissance: save %sp, -96, %sp cmp %i1, %g0 ble .PAS_DE_RECUR nop mov %i0, %o0 sub %i1, 1, %o1 call puissance nop smul %o0, %i0, %i0 ba .FIN nop .PAS_DE_RECUR: set 1, %i0 .FIN: ret restore

! 1 instruction = 4 octets ! puissance : symbole global

! ! ! ! !

place largument n 0 place largument n 1 appel de puissance(o0, 01, ...) -> resultat dans o0 i0 = i0 * o0

! --- donnees --.section ".rodata" .align 1 .SCANF0: .asciz "%d" .PRINTF0: .asciz "x^y = %d\n" ! --- instructions --.section ".text"

.align 4 .global main main: save %sp, -104, %sp ! rserve un cadre de pile de ! 96+8 = 104 octets ! ! ! ! ! ! ! ! 1er scanf place la valeur lue a ladresse donnee par fp-8 2eme scanf place la valeur lue a ladresse donnee par fp-4

ld [%fp-8], %o0 ld [%fp-4], %o1 call puissance nop mov %o0, %o1 set .PRINTF0, %o0 call printf nop clr %i0 ret restore

! charge le 1er argument ! le 2eme ! appelle la fonction

set .SCANF0, %o0 sub %fp, 8, %o1 call scanf nop set .SCANF0, %o0 sub %fp, 4, %o1 call scanf nop

! met le resultat en arg 1 ! la chaine en arg 0 ! et appelle printf

Vous aimerez peut-être aussi