逆アセンブリwindows htonl()関数

2700 ワード

システムカーネル書き込みネットワークプログラムではhtons htonlのような関数を呼び出して変換する必要がある場合があるが、カーネルはc実行ライブラリしか呼び出せないため、他のAPIは呼び出せない.自分も少しアセンブリに触れたことがありますが、習ったことがありません.古いコードの道を知っているこの本の前の章を見たことがあります.もし自分で逆コンパイルしてみたら、結局自分は本当に逆で、アセンブリを知っている人には確かに簡単です.
 
ULONG myHtonl(ULONG i)

{

	ULONG eax,edx,ecx;

	eax = i;

	edx = i;

	edx = edx << 16;

	eax = eax & 0x0ff00;

	eax = eax | edx;

	edx = i;

	edx = edx & 0x0ff0000;

	ecx = i >> 16;

	edx = edx | ecx;

	eax = eax << 8;

	edx = edx >> 8;

	eax = eax | edx;

	return eax;

}


変数はレジスタの名前で混同を避ける.自分はこのコードが少し問題があるかどうかを感じて、彼はどうして自分のシステムが小さい端かどうかを判断して変換して、もし自分のコンピュータがハイエンドだったらどうしますか?
後ろはネット上で一人でシミュレーションコードを書いたのを見た.
http://wxxweb.blog.163.com/blog/static/13512690020103145256909/
ypedef unsigned short int uint16;



typedef unsigned long int uint32;



 



//         



#define BigLittleSwap16(A)  ((((uint16)(A) & 0xff00) >> 8) | \



                                                 (((uint16)(A) & 0x00ff) << 8))



 



//         



#define BigLittleSwap32(A)  ((((uint32)(A) & 0xff000000) >> 24) | \



                                                 (((uint32)(A) & 0x00ff0000) >> 8) | \



                                                 (((uint32)(A) & 0x0000ff00) << 8) | \



                                                 (((uint32)(A) & 0x000000ff) << 24))



 



//       1,    0



int checkCPUendian()



{



       union{



              unsigned long int i;



              unsigned char s[4];



       }c;



 



       c.i = 0x12345678;



       return (0x12 == c.s[0]);



}



 



//   htonl  ,           



unsigned long int HtoNl(unsigned long int h)



{



       //       ,       ,    



       //       ,        



       return checkCPUendian() ? h : BigLittleSwap32(h);



}



 



//   ntohl  ,           



unsigned long int NtoHl(unsigned long int n)



{



       //       ,       ,    



       //       ,            



       return checkCPUendian() ? n : BigLittleSwap32(n);



}



 



//   htons  ,           



unsigned short int HtoNs(unsigned short int h)



{



       //       ,       ,    



       //       ,        



       return checkCPUendian() ? h : BigLittleSwap16(h);



}



 



//   ntohs  ,           



unsigned short int NtoHs(unsigned short int n)



{



       //       ,       ,    



       //       ,            



       return checkCPUendian() ? n : BigLittleSwap16(n);



}


彼自身が判断を追加したのを見て、windowsシステムはマクロを通じてhontsのこれらの関数を置き換えることを推定して、小さい端で変換内容を定義して、ハイエンドのハイエンドであれば定義して直接帰ってもいいと思います.このやり方でwindowsはこのようにコードを書くのが一番好きです.