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

ops/2024/10/18 18:25:41/

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


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

原理其实很简单:

解释一些概念

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

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

②字的概念

字的英文是word,

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

两个字是4个字节,在【#include <windows.h>】库中有相应的数据类型是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*),相当于保留低位双字舍弃高位双字

#include <bits/stdc++.h>
#include <windows.h> //字类型在这里面,但万能头文件里没有windows.h所以单独引入
//定义两个宏,分别用于截取高位和地位
#define HIDWORD(x) (*((DWORD*)&(x) + 1))
#define LODWORD(x) (*((DWORD*)&(x)))
int main() {int64_t dwValue; //dwValue = 0XAABBCCDD12345678;int32_t high = HIDWORD(dwValue);int32_t low = LODWORD(dwValue);printf("high = 0x%x, low = 0x%x", high, low); //输出high = 0xaabbccdd, low = 0x12345678return 0;
}


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

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

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

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

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

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


http://www.ppmy.cn/ops/20782.html

相关文章

【Jenkins】持续集成与交付 (五):Jenkins用户权限管理

【Jenkins】持续集成与交付 (五):Jenkins用户权限管理 1、安装插件(Role-based Authorization Strategy)2、开启权限全局安全配置3、创建角色4、创建用户5、给用户分配角色6、测试权限💖The Begin💖点点关注,收藏不迷路💖 1、安装插件(Role-based Authorization Stra…

为什么要学音视频?

一直都在说“科技改变生活”&#xff0c;现实告诉我们这是真的。 随着通信技术和 5G 技术的不断发展和普及&#xff0c;不仅拉近了人与人之间的距离&#xff0c;还拉近了人与物&#xff0c;物与物之间的距离&#xff0c;万物互联也变得触手可及。 基于此背景下&#xff0c;音…

【JavaEE网络】深入理解Socket套接字及其在网络编程中的应用

目录 Socket套接字UDP VS TCP有连接 VS 无连接可靠传输 VS 不可靠传输面向字节流 VS 面向数据报 全双工 VS 半双工 UDP数据报套接字编程DatagramSocket APIDatagramPacket APIInetSocketAddress APIUDP回显客户端服务器服务器和客户端的工作流程UDP翻译客户端服务器 Socket套接…

安全作业-1

1. windows登录的明文密码&#xff0c;存储过程是怎么样的&#xff0c;密文存在哪个文件下&#xff0c;该文件是否可以打开&#xff0c;并且查看到密文 用户在登录界面输入用户名和密码。Windows登录进程(winlogon.exe)接收用户的输入&#xff0c;并准备进行身份验证。Lsass处…

【数据结构】图的应用(最小生成树、拓扑排序、最短路径等)

文章目录 最小生成树概念Prim算法基于邻接表的Prim算法&#xff1a;基于邻接矩阵的Prim算法 Kruskal算法基于邻接表的Kruskal算法&#xff1a;基于邻接矩阵的Kruskal算法&#xff1a; 有向无环图及其应用拓扑排序概念基于邻接表的拓扑排序算法&#xff1a;基于邻接矩阵的拓扑排…

csdn的复制代码功能如何实现

页面布局分析&#xff1a; 按钮在文本框里面&#xff0c;所以文本框是父元素&#xff0c;按钮是子元素。要使得按钮在文本框的右上角&#xff0c;需要使用绝对定位。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8">…

libssl.so.10: cannot open shared object file: No such file or directory

在Ubuntu20上使用python调用一个公司自己开发的第三方库&#xff0c;运行时出现了如标题的问题。表示缺少该so文件。 网上有两种方法&#xff1a; 1.使用apy-install 来直接安装libssl1.0.0。&#xff08;简单但对我无效&#xff0c;低版本Ubuntu可尝试&#xff09; 2.从open…

c++理论篇(一) ——浅谈tcp缓存与tcp的分包与粘包

介绍 在网络通讯中,Linux系统为每一个socket创建了接收缓冲区与发送缓冲区,对于TCP协议来说,这两个缓冲区是必须的.应用程序在调用send/recv函数时,Linux内核会把数据从应用进程拷贝到socket的发送缓冲区中,应用程序在调用recv/read函数时,内核把接收缓冲区中的数据拷贝到应用…