跳到主要内容
区块链Mar 28, 2026

Deep EVM #6:Yul内存管理——mstore、mload和空闲内存指针

OS
Open Soft Team

Engineering Team

空闲内存指针

在Yul中操作内存时,理解Solidity的内存约定至关重要。0x40处的空闲内存指针追踪下一个可用的内存地址。

let freePtr := mload(0x40)
mstore(freePtr, someValue)
mstore(0x40, add(freePtr, 0x20))  // 推进指针

mstore和mload操作码

  • mstore(offset, value) — 在给定偏移量写入32字节
  • mload(offset) — 从给定偏移量读取32字节
  • mstore8(offset, value) — 写入单个字节

所有操作消耗3 gas加上潜在的内存扩展成本。

手动ABI编码

在Yul中为外部调用构建calldata是关键技能:

// 编码 transfer(address,uint256) 调用
mstore(0x00, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(0x04, recipient)
mstore(0x24, amount)
let success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)

内存扩展成本

内存成本遵循二次增长公式。对于小内存使用(低于~700字节),成本近似线性。但增长快速:1 KB约98 gas,10 KB约1160 gas,1 MB约2,001,000 gas。

外部调用数据构建

从Yul进行外部调用需要手动在内存中构建calldata,执行调用,然后处理返回数据。

内存高效模式

  1. 重用暂存空间(0x00-0x3f) — 用于临时哈希和小型计算
  2. 不要不必要地扩展内存 — 每次扩展都有二次成本
  3. 对齐到32字节边界 — EVM以32字节块操作
  4. 在内存中打包数据 — 最小化内存占用

总结

内存管理是高效Yul编程的核心。理解空闲内存指针、手动ABI编码和内存扩展成本使你能够编写紧凑、gas高效的代码,超越Solidity编译器的能力。