ASM

    http://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax

    Instructions

    CALL .LABEL

    PUSH IP
    JMP .LABEL
    

    PUSHL VAL

    SUB $4,%ESP
    MOV VAL,%(ESP)
    

    Remarque: Comme c'est un PUSHL ( long, soit 4 octet, on a SUB %%$%%4 )

    Exemple d'utilisation:

    /*
    main:
    .LFB0:
      pushl   %ebp
      movl    %esp, %ebp
    */
    
    int main(void){
    
    /*
      movl    $0, %eax
    	popl    %ebp
      ret
    */
    
      return 0;
    }
    

    Assembleur équivalent:

    main:
    .LFB0:
      pushl   %ebp
      movl    %esp, %ebp
      movl    $0, %eax
      popl    %ebp
    	ret
    

    LEAVE

    LEAVE

    est équivalent à

    MOV %ebp,%esp
    POP %ebp
    

    POP VAL

    mov %(esp), VAL
    add $4,%esp
    

    RET

    POP IP
    ADD $1,IP
    

    Examples

    In this example we implement a FIR filter.

    This ASM code is based on this C code.

    /*********************
    *** FONCTION : Algorithme de filtrage d'un filtre FIR (forme DIRECTE)  
    *** @brief : calculs sur entiers signes sur 16bits
    ***    
    *** @param coeff :     pointeur sur le tableau de coefficients
    *** @param x_dg :              pointeur sur le tableau d'echantillons
    *** @param nbCoeff :   taille des tableaux (ordre du filtre + 1)
    **********************/
    short FIR_C(short *coeff, short *x_dg, short nbCoeff){
      short y_dg=0;
      int i;
    
      for(i=0; i<nbCoeff; i++){
              y_dg += (coeff[i]*x_dg[i])>>15;
      }
    
      return y_dg;
    }
    

    Sample

    Standard ASM

    ;*********************************
    ; @file :  FIR_asm.asm
    ; @brief : Algorithme d'un filtre FIR - assembleur sans optimisation (utilisation de LDW)
    ; @author :
    ; last modification :
    ;*********************************
    
      .global         _FIR_asm                ; Permet de rendre le label accessible par d'autre fichier (idem extern en "C")
    
    
    _FIR_asm:                                               ; Preceder un label par "_" permet de le rendre accessible depuis un fichier "C"
    
      mv              a6,b0                           ; recuperation du nombre d'iterations dans b0 (taille du tableau)
      zero            a2
    LOOP:
      ldw             .d1             *a4++,a0        ; chargement d'un coef a dans a0
      nop                             4               ; respect du temps de deplacement memoire de LWD qui est 5. Donc 1 (l'instruction elle même) + 4 (via le NOP)
    
      ldw             .d2             *b4++,a1        ; chargement d'un echantillon x dans a1
      nop                             4
    
      mpy             .m1             a0,a1,a3        ; multiplication de la partie basse
      nop                             1
    
      mpyh            .m1             a0,a1,a5        ; multiplication de la partie haute
      nop                             1
    
      add             .l1             a2,a3,a2        ; a2 += a3 (ajout partie basse). Remarque: ordre important, d'abord partie basse, puis haute.
      add             .l1             a2,a5,a2        ; a2 += a5 (ajout partie haute). Remarque: Les résultats se trouve dans a2
    
      sub             .s2             b0,2,b0         ; decremente de 2 car on charge deux echantillons (ldw, charge 32 bits)
    
      [b0] b          .s1             LOOP
    
      nop                             5               ; l'instruction b prend 6 cycles d'horloges
    
      mv              .d1             a2,a4           ; la sortie de la fonction doit se trouver dans A4
    
      b               .s2             b3              ; Branchement sur l'adresse de retour, sauvee dans B3 avant de rentrer dans la fonction
      shr             .s1             a4,15,a4        ; y_dg += (coeff[i]*x_dg[i])   >>15; (decalage de 15)
    

    Pipeline ASM

    First you've to do some work like this:

    Then you can write the ASM code:

    ;*********************************
    ; @file :  FIR_asmPipe.asm
    ; @brief : Algorithme d'un filtre FIR - assembleur avec optimisation (pipelining software - utilisation de LDW)
    ; @author :
    ; last modification :
    ;*********************************
    
    	.global		_FIR_asmPipe		; Permet de rendre le label accessible par d'autre fichier (idem extern en "C")
    
    
    _FIR_asmPipe:
    
    	mv A6,B0
    	zero A2
    	zero B2
    
    c1			LDW 	.D1 	*A4++,A7
    	|| 		LDW 	.D2 	*B4++,B7
    
    c2			LDW 	.D1 	*A4++,A7
    	|| 		LDW 	.D2 	*B4++,B7
    	|| [B0]	SUB 	.S2 	B0,2,B0
    
    c3			LDW 	.D1 	*A4++,A7
    	|| 		LDW 	.D2 	*B4++,B7
    	|| [B0]	SUB 	.S2 	B0,2,B0
    	|| [B0]	B 		.S1 	LOOP
    
    c4			LDW 	.D1 	*A4++,A7
    	|| 		LDW 	.D2 	*B5++,B7
    	|| [B0] SUB 	.S2 	B0,2,B0
    	|| [B0] B 		.S1 	LOOP
    
    c5			LDW 	.D1 	*A4++,A7
    	|| 		LDW 	.D2 	*B4++,B7
    	|| [B0]	SUB 	.S2 	B0,2,B0
    	|| [B0]	B 		.S1 	LOOP
    
    c6			LDW 	.D1 	*A4++,A7
    	|| 		LDW 	.D2 	*B4++,B7
    	|| [B0]	SUB 	.S2 	B0,2,B0
    	|| [B0]	B 		.S1 	LOOP
    	|| MPYH 		.M1 	A7,B7,A5
    	|| MPY 			.M2 	A7,B7,B5
    
    c7			LDW 	.D1 	*A4++,A7
    	|| 		LDW 	.D2 	*B4++,B7
    	|| [B0]	SUB 	.S2 	B0,2,B0
    	|| [B0]	B 		.S1 	LOOP
    	|| 		MPYH 	.M1 	A7,B7,A5
    	|| 		MPY 	.M2 	A7,B7,B5
    
    LOOP:		LDW 	.D1 	*A4++,A7
    	||		LDW 	.D2 	*B4++,B7
    	|| [B0]	SUB 	.S2 	B0,2,B0
    	|| [B0]	B 		.S1 	LOOP
    	|| 		MPYH 	.M1 	A7,B7,A5
    	||		MPY 	.M2 	A7,B7,B5
    	||		ADD 	.L1 	A2,A5,A2
    	||		ADD 	.L2 	B2,B5,B2
    
    	ADD A2,B2,A4
    
    	B		.s2		b3			; Branchement sur l'adresse de retour, sauvée dans B3 avant de rentrer dans la fonction
    	SHT		.s1		a4,15,a4	; y_dg += (coeff[i]*x_dg[i])   >>15; (decalage de 15)
    	NOP				4
    	4