• 反汇编windows htonl()函数


    因为自己在系统内核写网络程序有时候需要调用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最喜欢这样写代码了。

    点滴记录自己的成长,一步一步进步。 把写代码当成吃饭,我想我会成为牛魔王的。
  • 相关阅读:
    Redis源码分析(三十四)--- redis.h服务端的实现分析(1)
    Redis源码分析(三十四)--- redis.h服务端的实现分析(1)
    Redis源码分析(三十三)--- redis-cli.c客户端命令行接口的实现(2)
    C# 接口
    C#属性有什么作用
    字节跳动面试总结
    大厂Redis高并发场景设计,面试问的都在这!
    上班摸鱼 手敲求水仙花数的代码!
    有一群志同道合的程序员朋友是怎样的体验?
    SpringBoot四大核心之自动装配——源码解析
  • 原文地址:https://www.cnblogs.com/c-study/p/3725739.html
Copyright © 2020-2023  润新知