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;
}
}