为何在非32倍数内存地址存储值会溢出到下一个地址?
Yul中mstore存储位置异常的原因解析
示例代码
mstore(0x24, 0x0443455243)
现象说明
- 若使用
mstore(0x20, 0x0443455243),整个值会被完整存储在内存地址0x20对应的32字节块中。 - 但如果使用
mstore(0x24, 0x0443455243),原本预期值从0x24开始存储,实际却看到首字节出现在0x20对应的块末尾,剩余4字节落在0x40对应的块开头。

原因解析
出现这种现象本质是EVM内存存储规则和Remix调试界面显示逻辑共同作用的结果:
- mstore指令强制写入32字节数据:EVM中
mstore的第二个参数会被自动扩展为256位(32字节)的值,哪怕你传入的数值长度不足。比如0x0443455243会被左填充27个0,变成0x000000000000000000000000000000000000000000000000000443455243。 - 内存按字节连续存储:
mstore(p, v)会把32字节的数据从地址p开始依次写入内存,最高位字节(填充的0)存在p,数值的有效字节会落在p+27到p+31的位置。 - Remix按32字节块分组显示内存:调试界面里的每个“内存块”对应32字节的连续区间(比如
0x20-0x3F是一个块,0x40-0x5F是下一个块)。
对应到你的例子:
- 用
mstore(0x20, ...)时,32字节数据从0x20开始,有效字节正好都在0x20-0x3F这个块里,所以看起来整个值都存在0x20处。 - 用
mstore(0x24, ...)时,32字节从0x24开始写:前28个填充的0写到0x24-0x3F(属于0x20块的后半段),第一个有效字节0x04写到0x3F(0x20块的最后一个位置);剩下的4个有效字节则写到0x40-0x43(0x40块的开头),这就造成了你看到的“跨块”现象。
内容的提问来源于stack exchange,提问作者Sohail Saha
相关产品推荐
相关产品推荐

