字节存储顺序主要分为大端序
(Big-endian)和小端序
(Little-endian),区别如下
- Big-endian:高位字节存入低地址,低位字节存入高地址
- Little-endian:低位字节存入低地址,高位字节存入高地址
例如,将12345678h
写入1000h
开始的内存中,以大端序和小端序模式存放结果如下
![1c47a990b4bda0f3daba9e2a21db5290.png](https://i-blog.csdnimg.cn/blog_migrate/15b4e253a564e2cced67787d654601eb.jpeg)
一般来说,x86系列CPU都是Little-endian
字节序,PowerPC通常是Big-endian
字节序。
因为网络协议也都是采用Big-endian方式传输数据的,所以有时也把Big-endian方式称为网络字节序
下面通过一个简单的例子继续理解小端序
#include "windows.h"
BYTE b = 0x12;
WORD w = 0x1234;
DWORD dw = 0x12345678;
char str[] = "abcde";
int main(int argc, char* argv[])
{
byte lb = b;
WORD lw = w;
DWORD ldw = dw;
char* lstr = str;
return 0;
}
通过visual studio调试一下,转到反汇编查看反汇编代码
可以看到全局变量b
、w
、dw
、str
的地址分别为06AA000h
、06AA004h
、06AA008h
、06AA00Ch
。我们在内存窗口查看相应的地址,可以看到对应的数据,上面不同颜色的方框对应不同变量。
![face98567bc415d221c2ecf7daac9b16.png](https://i-blog.csdnimg.cn/blog_migrate/394ab853f1a38c2916446381dc79480d.jpeg)
拿dw
这个变量来说,他的地址是06AA008h
,可以看到他的数据是0x78
0x56
0x34
0x12
,注意小端序是地址高位存储数据的高位,地址低位存储数据的低位
![f181f470b031111417e82c25df5aaf4e.png](https://i-blog.csdnimg.cn/blog_migrate/f69ec4033bd024d7e20b3f819150ba26.jpeg)
而字符串“abcde”
被保存在一个字符(char)数组str中,字符数组在内存中是连续的,此时向字符数组存放数据,无论是采用大端序还是小端序,存储顺序都相同。
还有另个知识点,就是注意到反汇编代码中的ptr
了吗,逆向分析的时候是不是经常看见这个符号,知道他是干什么的吗?
PTR运算符可以重写操作数默认的大小类型,ptr
的前面会有类型的声明,比如byte ptr [b(06AA000h)]
,他的意思从这个地址取一个byte
大小的数据。比如byte ptr [dw(06AA008h)]
得到的就是0x78
, word ptr [dw(06AA008h)]
得到的就是0x5678
,以此类推。