Comment cree de nouveau instruction en asm pour optimizer le tcp/ip

Contenu du snippet

INSTRUCTIONS ASSEMBLEUR POUR APPLICATION DE TCP/IP:

Dans le domaine du tcp/ip , l?implementation de code ecrit en language c/c++ ,
est tres mal traduit en assembleur(c.a.d. par tres optimal ) ce qui rend ces applications extrement dur a implemente sur des processeur conventionnel.

Dans ma recherche j?ai remarque qu?avec l?aide de quelque instructions specials en assembleur ajoute a tous processeur standard et une methode algorithmique simple on pouvait arrive a un code beaucoup plus rapide c.a.d. moins de cycles.

Un code typique de tcp ou networking a l?allure suivante :

If( (a > b) && (d == f) )
{
d = f + d ;
k = s+ 5 ;
send_message() ; // return
}

if( (k == 3) || ( l < d))
{

ss = val1 + val2 ;
s1 = ss << 2 ;

if(dd == 3)
{
ss01 = val11 + val12 ;
s01 = ss11 << 2 ;
}

if(k > 10)
{
ss02 = val12 + val22 ;
s02 = ss21 << 2 ;
}

if(r >= v)
{
ss03 = val13 + val32 ;
s03 = ss31 << 2 ;
}

send_message() ; // return

}
else
{
ss = val1 + val2 ;
s1 = ss << 2 ;

if(dd > 123)
{
ss04 = val41 + val14 ;
s04 = ss14 << 2 ;
}

if(k == 110)
{
ss05 = val52 + val52 ;
s05 = ss25 << 2 ;
}

if(r == v)
{
ss05 = val15 + val52 ;
s05= ss51 << 2 ;
}
send_message() ; // return

}

ce code peut etre vue selon la theorie des graphe de la facon suivante:



c?est a dire que l?on peut prendre tout code est le transforme en ce type de code:

donc en premier lieu on doit cree un comparateur qui mettrais le resultat dans un registre qui emmagazinerais un nombre de resultat:

appelons CMPTSTR1GT reg1,reg2

cette fonction compare si reg1 est plus grand que reg2 et fait le mecanisme suivant:

si vrai
reg_result = reg_result << 1 ;
reg_result = reg_result | 1 ;

si faux
reg_result = reg_result << 1 ;
reg_result = reg_result | 0 ;

donc supposons que l?on a trois comparateur le premier vraie le second faux et le troisieme vrai voyons le regitre reg_result:

au debut reg_result = 0
CMPTSTR1LT reg1,reg2
La comparation est vrai donc
reg_result = reg_result << 1 ;
reg_result = reg_result | 1 ;
donc reg_result = 1
CMPTSTR1EQ reg3,reg4
La comparation est faux donc
reg_result = reg_result << 1 ;
reg_result = reg_result | 0 ;
donc reg_result = 2

CMPTSTR1GE reg5,reg6
La comparation est vrai donc
reg_result = reg_result << 1 ;
reg_result = reg_result | 1 ;
donc reg_result = 5 soit en binaire 101b

donc en voyons le resultat binaire nous pouvons immediatement voir que le premiere comparaison est vrai la seconde fausse et la troisieme vrai.

Revenons au code c d?ecrit plus tot et ecrivons tout les comparaison grace a l?instruction assembleur CMPTST :

CMPTSTR1GT a,b // if (a > b) bit numero 9 du reg_result
CMPTSTR1EQ d,f // if (d == f) bit numero 8 du reg_result
CMPTSTIEQ k,3 // if (k == 3) bit numero 7 du reg_result
CMPTSTR1LT l,d // if ( l < d) bit numero 6 du reg_result
CMPTSTIEQ dd,3 // if(dd == 3) bit numero 5 du reg_result
CMPTSTIGT k,10 // if(k > 10) bit numero 4 du reg_result
CMPTSTR1GE r,v // if(r >= v) bit numero 3 du reg_result
CMPTSTIGT dd,123 // if(dd > 123) bit numero 2 du reg_result
CMPTSTIEQ k,110 // if(k == 110) bit numero 1 du reg_result
CMPTSTR1EQ r,v // if(r == v) bit numero 0 du reg_result

Ce qui nous donne pour reg_result un vecteur binaire de 10 bits.



Si la condition suivant est vraie If( (a > b) && (d == f) ) c?est a dire que les bit 9 est 8 ont la valeur 1 on ecxecute ce qui se trouve a l?interieur de l?accollade est onfini si la condition est fause on saute a la seconde condition if( (k == 3) || ( l < d)) ce qui nous ammenne a regarde les bits 7 et 6 et selon le resultat leur associe les bit 5 4 3 ou
2 1 0.

Notons bit(n) le bit numero n, donc pour ce cas on a :

Si [bit(9) & bit(8)] vrai alors : donnons la valeur binaire 1 0 0 0 0
Si [bit[7] | bit(6)] vrai alors : prenons la valeur binaire 1 bit(5) bit(4) bit(3)
Si [bit[7] | bit(6)] faux alors : prenons la valeur binaire 0 bit(2) bit(1) bit(0)

La function MRD fait ce qui est decrit plus haut :

Son implementation est la suivante :

MRD reg_result,Immediate num of 16 bits
Implementation c de la function MRD est en fin du document. Puis viens la foction
Branch test qui s?ecrit BTST label,num

Elle fait la chose suivante prend reg_result * 2exp(num +1)

Donc en fait le code c devient :

CMPTSTR1GT a,b // if (a > b)
CMPTSTR1EQ d,f // if (d == f)
CMPTSTIEQ k,3 // if (k == 3)
CMPTSTR1LT l,d // if ( l < d)
CMPTSTIEQ dd,3 // if(dd == 3)
CMPTSTIGT k,10 // if(k > 10)
CMPTSTR1GE r,v // if(r >= v)
CMPTSTIGT dd,123 // if(dd > 123)
CMPTSTIEQ k,110 // if(k == 110)
CMPTSTR1EQ r,v // if(r == v)
MRD RESULT,0x9038 // the input vector is 10 bit for example 1100101011
// the output of the MRD function is between 0 0 0 0 0 to 10111
BTSTC label001,2 // jump to the good case , 2 => each case is 8 lentgh opcode
// btsct perform the result , for example 01011 = 11 decimal * 8 and jump to //label001*11
Label001:
// 0 0 0 0 this case correpond to if( (k == 3) || ( l < d)) is false
ss = val1 + val2 ;
s1 = ss << 2 ;
send_message() ; // return

// 0 0 0 1 this case correpond to if( (k == 3) || ( l < d)) is false
ss = val1 + val2 ;
s1 = ss << 2 ;
ss05 = val15 + val52 ;
s05= ss51 << 2 ;
send_message() ; // return

// 0 0 1 0 this case correpond to if( (k == 3) || ( l < d)) is false
ss = val1 + val2 ;
s1 = ss << 2 ;
ss05 = val52 + val52 ;
s05 = ss25 << 2 ;
send_message() ; // return

// 0 0 1 1 this case correpond to if( (k == 3) || ( l < d)) is false
ss = val1 + val2 ;
s1 = ss << 2 ;
ss05 = val52 + val52 ;
s05 = ss25 << 2 ;
ss05 = val15 + val52 ;
s05= ss51 << 2 ;
send_message() ; // return

// 0 1 0 0 this case correpond to if( (k == 3) || ( l < d)) is false
ss = val1 + val2 ;
s1 = ss << 2 ;
ss04 = val41 + val14 ;
s04 = ss14 << 2 ;
send_message() ; // return

// 0 1 0 1 this case correpond to if( (k == 3) || ( l < d)) is false
ss = val1 + val2 ;
s1 = ss << 2 ;
ss04 = val41 + val14 ;
s04 = ss14 << 2 ;
ss05 = val15 + val52 ;
s05= ss51 << 2 ;
send_message() ; // return

// 0 1 1 0 this case correpond to if( (k == 3) || ( l < d)) is false
ss = val1 + val2 ;
s1 = ss << 2 ;
ss04 = val41 + val14 ;
s04 = ss14 << 2 ;
ss05 = val52 + val52 ;
s05 = ss25 << 2 ;
send_message() ; // return

// 0 1 1 1 this case correpond to if( (k == 3) || ( l < d)) is false
ss = val1 + val2 ;
s1 = ss << 2 ;
ss04 = val41 + val14 ;
s04 = ss14 << 2 ;
ss05 = val52 + val52 ;
s05 = ss25 << 2 ;
ss05 = val15 + val52 ;
s05= ss51 << 2 ;
send_message() ; // return

// 1 0 0 0 this case correpond to if( (k == 3) || ( l < d)) is true
ss = val1 + val2 ;
s1 = ss << 2 ;
send_message() ; // return

// 1 0 0 1 this case correpond to if( (k == 3) || ( l < d)) is true
ss = val1 + val2 ;
s1 = ss << 2 ;
ss03 = val13 + val32 ;
s03 = ss31 << 2 ;
send_message() ; // return

// 1 0 1 0 this case correpond to if( (k == 3) || ( l < d)) is true
ss = val1 + val2 ;
s1 = ss << 2 ;
ss02 = val12 + val22 ;
s02 = ss21 << 2 ;
send_message() ; // return

// 1 0 1 1 this case correpond to if( (k == 3) || ( l < d)) is true
ss = val1 + val2 ;
s1 = ss << 2 ;
ss02 = val12 + val22 ;
s02 = ss21 << 2 ;
ss03 = val13 + val32 ;
s03 = ss31 << 2 ;
send_message() ; // return

// 1 1 0 0 this case correpond to if( (k == 3) || ( l < d)) is true
ss = val1 + val2 ;
s1 = ss << 2 ;
ss01 = val11 + val12 ;
s01 = ss11 << 2 ;
send_message() ; // return

// 1 1 0 1 this case correpond to if( (k == 3) || ( l < d)) is true
ss = val1 + val2 ;
s1 = ss << 2 ;
ss01 = val11 + val12 ;
s01 = ss11 << 2 ;
ss03 = val13 + val32 ;
s03 = ss31 << 2 ;
send_message() ; // return

// 1 1 1 0 this case correpond to if( (k == 3) || ( l < d)) is true
ss = val1 + val2 ;
s1 = ss << 2 ;
ss01 = val11 + val12 ;
s01 = ss11 << 2 ;
ss02 = val12 + val22 ;
s02 = ss21 << 2 ;
send_message() ; // return

// 1 1 1 1 this case correpond to if( (k == 3) || ( l < d)) is true
ss = val1 + val2 ;
s1 = ss << 2 ;
ss01 = val11 + val12 ;
s01 = ss11 << 2 ;
ss02 = val12 + val22 ;
s02 = ss21 << 2 ;
ss03 = val13 + val32 ;
s03 = ss31 << 2 ;
send_message() ; // return

// 1 0 0 0 0 this case correpond to If( (a > b) && (d == f) ) is true

d = f + d ;
k = s+ 5 ;
send_message() ; // return



Implementation de la function mrd en c :

Void MRD(reg_result,Immediate_num)
{

imm1 = (Immediate_num & 0xff00) >> 8 ;

imm2 = (Immediate_num & 0xff);


pilot2_exist = (imm1 >> 4) & 0x1 ; // if 1 exist
pilot2_lentgh = (imm1 >> 3) & 0x1 ;// if 0 length 1 bit if 1 length 2 bit
pilot2_operator = (imm1 >> 2) & 0x1 ;// if 0 do or between 2 bit if 1 do and
pilot2_true = imm1 & 0x3 ;// take the length

pilot1_length = (imm2 >> 7 ) & 1 ;// if 0 length 1 bit if 1 length 2 bit
pilot1_operator = (imm2 >> 6) & 1;// if 0 do or between 2 bit if 1 do and
map_result = (imm2 >> 4 ) & 3 ;
pilot1_true = (imm2 & 12 ) >> 2;// take the length
pilot1_false = imm2 & 0x3 ;// take the length

switch(pilot1_false)
{
case 0:
val_pilot1_false = reg_result & 0x0 ;
reg_result = reg_result >> 0 ;
break;

case 1:
val_pilot1_false = reg_result & 0x1 ;
reg_result = reg_result >> 1 ;
break;

case 2:
val_pilot1_false = reg_result & 0x3 ;
reg_result = reg_result >> 2 ;
break;

case 3:
val_pilot1_false = reg_result & 0x7 ;
reg_result = reg_result >> 3 ;
break;

}

switch(pilot1_true)
{
case 0:
val_pilot1_true = reg_result & 0x0 ;
reg_result = reg_result >> 0 ;
break;

case 1:
val_pilot1_ true = reg_result & 0x1 ;
reg_result = reg_result >> 1 ;
break;

case 2:
val_pilot1_ true = reg_result & 0x3 ;
reg_result = reg_result >> 2 ;
break;

case 3:
val_pilot1_ true = reg_result & 0x7 ;
reg_result = reg_result >> 3 ;
break;

}

if(pilot1_length)
{
val_pilot1 = reg_result & 0x1 ;
reg_result = reg_result >> 1 ;
}
else
{
val_pilot1 = reg_result & 0x3 ;
reg_result = reg_result >> 2 ;
}

switch(pilot2_true)
{
case 0:
val_pilot2_true = reg_result & 0x0 ;
reg_result = reg_result >> 0 ;
break;

case 1:
val_pilot2_ true = reg_result & 0x1 ;
reg_result = reg_result >> 1 ;
break;

case 2:
val_pilot2_ true = reg_result & 0x3 ;
reg_result = reg_result >> 2 ;
break;

case 3:
val_pilot2_ true = reg_result & 0x7 ;
reg_result = reg_result >> 3 ;
break;

}

if(pilot2_length)
{
val_pilot2 = reg_result & 0x1 ;
reg_result = reg_result >> 1 ;
}
else
{
val_pilot2 = reg_result & 0x3 ;
reg_result = reg_result >> 2 ;
}

switch (map_result)
{
case 0 :
pilot2_base = 0x10 // 1 0 X X X
pilot1_base_true = 8 // 1 X X X
pilot1_base_false = 0 // 0 X X X
break;
case 1 :
pilot2_base = 0x0 // 0 0 X X
pilot1_base_true = 8 // 1 0 X X
pilot1_base_false = 12 // 1 1 X X
break;

case 2 :
pilot2_base = 0x0 // 0 X X
pilot1_base_true = 8 // 1 X X X
pilot1_base_false = 4 // 0 1 X X
break;

case 3 :
pilot2_base = 0x10 // 1 0 X X X
pilot1_base_true = 8 // 1 0 X X
pilot1_base_false = 4 // 0 1 X X
break;


}

if(pilot2_exist)
{

if(pilot2_length)
{
bit1 = val_pilot2 & 1 ;
bit2 = (val_pilot2 >> 1)>>1 ;
if(pilot2_operator)
{
res_val_pilot2 = bit1 & bit2 ;
}
else
{
res_val_pilot2 = bit1 | bit2 ;
}
}
else
{
res_val_pilot2 = val_pilot2 ;
}

if(pilot1_length)
{
bit1 = val_pilot1 & 1 ;
bit2 = (val_pilot1 >> 1)>>1 ;
if(pilot1_operator)
{
res_val_pilot1 = bit1 & bit2 ;
}
else
{
res_val_pilot1 = bit1 | bit2 ;
}
}
else
{
res_val_pilot2 = val_pilot1 ;
}

if(pilot2_exist)
{
if(res_val_pilot2)
{
reg_result = pilot2_base | val_pilot2_true ;
return;
}
}

if(res_val_pilot1)
{
reg_result = pilot2_base | pilot1_base_true ;
return;
}
else
{
reg_result = pilot2_base | pilot1_base_false ;
return;
}
}

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.