The hard ways

大小端序

大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;

小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

比如现在有一块四个字节的内存,并且地址是从左往右递增的。为了方便,都置为 0

1000:1000 00 00 00 00

现有一个十六进制数 0x12345678,这个十六进制数刚好可以使用上面的那块内存去存放,因为它们都是 32bits。

大端序

如果是大端序,内存表现将会是这样

1000:1000 12 34 56 78

可以发现,12 是原十六进制数 0x12345678的高位,而这个 12 放在上面那块内存地址的最低单元中(因为前面说了,这块内存地址是从左往右递增的,所以左边是相对低位,右边是相对高位)。这就是这段话的意思

大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中

小端序

如果是小端序,内存表现是这样的

1000:1000 78 56 34 12

可以发现,78 是原十六进制数 0x12345678的低位,而此时它也放在了最低的内存单元中,这就是这段话的意思

小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中

另外,可以发现,大小端序对字节内容是没有影响的,12还是 12 并没有变成 21

另外,对于类似下面情形,一般为内存或者文件 dump 工具的输出内容,通常的阅读顺序是,从左往右、从上到下:

0AEC:0000  CD 20 FF 9F 00 9A EE FE-1D F0 4F 03 50 05 8A 03
0AEC:0010  50 05 17 03 50 05 16 04-01 01 01 00 02 FF FF FF
0AEC:0020  FF FF FF FF FF FF FF FF-FF FF FF FF 06 05 4E 01
0AEC:0030  10 0A 14 00 18 00 EC 0A-FF FF FF FF 00 00 00 00
0AEC:0040  05 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
0AEC:0050  CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20
0AEC:0060  20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20
0AEC:0070  20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00

8086 端序

如何知道当前的 8086 是大端序还是小端序,可以使用下面的汇编代码测试

; 设置 data segment 的段地址
mov ax, 1000
mov ds, ax

; 一次将一个字的数据 0001h 写入数据段的第一个单元开始的一个字的内存中
; 一个字占用 2 个字节,那么如果是大端序,内存中应该是 00 01
; 如果是小端序,内存中就会使 01 00
mov ax, 1h
mov [0], ax

; 先将 bx 置 0,便于下面的查看
sub bx, bx

; 将数据段中的第一个内存单元的内容放置到 bl 中,因为 bl 是 8 位的,所以这样可以
; 达到只获取第一个字节的目的,现在可以查看寄存器 bx 的值,如果它是 0001,则说明
; 内存中的数据是 01 00 这样的格式,则设备是小端序的,反之亦然
mov bl, [0]
Made with gadget