因为自己在系统内核写网络程序有时候需要调用htons htonl 这样的函数进行转换,但由于内核只能调用c运行库,别的API不能调用。自己也接触过一点汇编,从来没有去学过。看过老码识途这本书前几章,如是自己反编译试了一下,结果自己还真反出来,对于懂汇编的人确实非常容易。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
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/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 |
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最喜欢这样写代码了。
反汇编windows htonl()函数,布布扣,bubuko.com
原文:http://www.cnblogs.com/c-study/p/3725739.html