目录
0. 问题
1. 对于从内存读取/写入的数据
2. 对于从常量直接写入寄存器
0. 问题
mov eax, 0x78FF5ABC //eax里存的是0x78FF5ABC
mov ebx,'WXYZ' //ebx里存的是0x5a595857,对应于ZYXW
为什么0x78FF5ABC以原序存于寄存器,而'WXYZ'却已逆序存于寄存器?需要从内存的读取写入说起。
1. 对于从内存读取/写入的数据
寄存器一直以一个方向读取内存,也是从低位到高位从寄存器中读取并写入内存的。演示如下:
- 从内存读取数值与字符串的顺序:
实际值: 0x78 ff 5a bc w x y z
在内存中存的值: 0xbc 5a ff 78 57 58 59 5a
读取内存到寄存器的顺序: ————> ————>
读取入寄存器的顺序: 00 00 00 bc 00 00 00 57(w)
即从reg的低位往高位处理:<———— <————
读取后,寄存器中的顺序为:78 ff 5a bc 5a 59 58 57
- 将值从寄存器写入到内存
将值从寄存器写入到内存,顺序为依然是寄存器从低位往高位处理:
寄存器的值: 78 ff 5a 00 z y x 00
<———— <————
内存的值: bc 00 00 00 57 00 00 00
————> ————>
写入后内存中的值: 0xbc 5a ff 78 57 58 59 5a
(这里的00只表示这个字节已经被处理或者还未被处理,不表示实际值,实际值是不变的)
2. 对于从常量直接写入寄存器
- 对于从常量直接写入寄存器,编译器对待数值与string两种常量采用了不同的策略:
- 对于数值,以原序存于寄存器,这样写入内存时可以符合小端。
- 对于字符串,为了让其能以原序存于内存中,需要以与内存相反的方向存于寄存器中,这样从内存读入寄存器后,才是正确的顺序。
对于直接从常量读取到寄存器的,为了保证在寄存器中的序列与【从内存中读取该实际值的序列】一致(即上面标红的部分),不能像从内存中读取字节一样都是——>这个方向,而是对于数值类型,要以<——这个方向读取,对于字符串类型,要以——>这个方向读取,即:
为什么在寄存器需要保持与标红部分一致呢?
一是为了后续执行从寄存器中写入内存后,可以保证字节在内存中的顺序正确。二是这样寄存器必须以这样的字节序列存储,才能解释成目标值。
所以与从内存中读取的区别是,寄存器直接读取数值型常量时,需要知道我这次不是从内存中读,对于常量数值,得手动逆序读取字节。
这里的字节读取顺序仅为易于理解,实际上寄存器的值是一次读取完的,不存在读取了一半的情况。
参考:x86 - Endianness inside CPU registers - Stack Overflow