• 64位整数高低位的数据获取与赋值操作探讨


    参考本篇->LOWORD和HIWORD函数_hidword-CSDN博客 


    一,如何获取一个64位整数的高32位和低32位

    原理其实很简单:

    解释一些概念

    ①十六进制和二进制直接挂钩

    一个十六位的十六进制数【0XAABBCCDD12345678】转为二进制的过程是把其中的每个数转为对应的二进制,如下图所示:

    ②字的概念

    字的英文是word,

    一个字是2个字节,在【#include 】库中有相应的数据类型是WORD

    两个字是4个字节,在【#include 】库中有相应的数据类型是DWORD,加个D就是double的意思

    没有操作四个字的数据类型(也可能是博主孤陋寡闻了,有错恳请指出)

    使用字类型来操作数据和使用基本数据类型操作数据本质是相同的,例如下图,DWORD操作4个字节,int也操作4个字节,因此它们的指针都能对整数变量的地址进行正确操作(这也是为什么逆向分析过程中工具的反汇编代码大都不用int*来表示4字节指针而是用DWORD*)

    ③大、小端存储

    “计算机只存储二进制数据”算是个只要看到这篇博客的人就肯定清楚的概念,但存放的顺序并不统一,高前低后为大端(高低指数据的高位地位,前后指内存地址前后,较小的地址在前),因此大端模式是按数据的正序来存储的,小端则反之

    另外,存储时是以字节(4个bit位,即4个二进制数或者说1个十六进制数)为一个单位来存储的,因此所说的大、小端正反排序针对的是每个字节,具体到每个字节对应的二进制bit位则都是正序的,如下图所示!

    有了上面的概念就能解释清楚下面的代码了——

    HIDWORD(x):将x的地址强转为双字指针(DWORD*)后加一,等于跳过一个字指向高位(小端存储,高位在后),最后解引用获得高位的双字(DWORD)数据即高32位

    LODWORD(x):将x的地址强转为双字指针(DWORD*),原本指向“四字”数据的地址强转为双字指针(DWORD*),相当于保留低位双字舍弃高位双字

    1. #include
    2. #include //字类型在这里面,但万能头文件里没有windows.h所以单独引入
    3. //定义两个宏,分别用于截取高位和地位
    4. #define HIDWORD(x) (*((DWORD*)&(x) + 1))
    5. #define LODWORD(x) (*((DWORD*)&(x)))
    6. int main() {
    7. int64_t dwValue; //
    8. dwValue = 0XAABBCCDD12345678;
    9. int32_t high = HIDWORD(dwValue);
    10. int32_t low = LODWORD(dwValue);
    11. printf("high = 0x%x, low = 0x%x", high, low); //输出high = 0xaabbccdd, low = 0x12345678
    12. return 0;
    13. }


    二,如何对一个64位整数的高/低位赋值

    标题【】所探讨的仅是如何获取高/低位的数据,如何对一个64位整数的高/低位赋值呢?

    例如一个64位整数为【0x123456abdc654321】,对其高位赋值为a1b1c1d1后的结果为【0xa1b1c1d1dc654321】,效果为改变了原数据的前半部分,对低位赋值的效果同理,这样的效果要如何编程实现?留下博主的一些拙见——

    注意这里的数据类型都要定义成无符号的,否则会出现部分数据赋值错误的情况,主要原因是对于有符号32位整数强转为64位整数后的数据前面补的是f而不是0(即int32_t num = 0xabcd1234强转为int64_t的结果是0xffffffffabcd1234而不是0x00000000abcd1234,前者会导致计算数据错误)

    1. uint64_t hidword(uint64_t num, uint32_t high_value){ //(num:预期赋值的64位有符号整数, high_value:预赋值的32位有符号整数即高位值)
    2. return (uint64_t)LODWORD(num) + ( (uint64_t)high_value << 32 ); //注意要先将其强制转换为64位后再左移32位,得到的结果与num的低位相加(即对高位赋值=旧低位+新高位)
    3. }
    4. uint64_t lodword(uint64_t num, uint32_t low_value){ //同理
    5. uint64_t h = (uint64_t)HIDWORD(num) << 32;
    6. uint64_t l = (uint64_t)low_value;
    7. return h + l; //(对低位赋值=旧高位+新低位,注意HIDWORD只是获取到高位的数据,还得用左移32位让该数据到真实的高位)
    8. }

    下面是运行测试结果,这里输出的名字单纯为了对齐数据

  • 相关阅读:
    混沌学院-亚朵酒店案例-观后随心谈
    图像处理:坐标变换
    非遗造物 匠心守护 南亚风情第壹城非遗文化节等你来玩
    编程小白的自学笔记十七(python办公自动化操作EXCEL表格之作图)
    数学建模美赛入门
    网站提示Internal Server Error的原因和解决方法分享
    LPL Ban/Pick 选人阶段的遮罩效果是如何实现的?
    2022 华为 Java 高级面试题及答案
    Hadoop3.0大数据处理学习1(Haddop介绍、部署、Hive部署)
    SSM框架学习记录-Spring_day02
  • 原文地址:https://blog.csdn.net/liKeQing1027520/article/details/138139079