区块链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,执行调用,然后处理返回数据。
内存高效模式
- 重用暂存空间(0x00-0x3f) — 用于临时哈希和小型计算
- 不要不必要地扩展内存 — 每次扩展都有二次成本
- 对齐到32字节边界 — EVM以32字节块操作
- 在内存中打包数据 — 最小化内存占用
总结
内存管理是高效Yul编程的核心。理解空闲内存指针、手动ABI编码和内存扩展成本使你能够编写紧凑、gas高效的代码,超越Solidity编译器的能力。