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