小端机器上读取数值、字符串到寄存器的实现

目录

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值