[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-6-yul-neicun-guanli-mstore-mload":3},{"article":4,"author":54},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":34,"related_articles":35},"d3000000-0000-0000-0000-000000000106","a0000000-0000-0000-0000-000000000032","Deep EVM #6：Yul内存管理——mstore、mload和空闲内存指针","deep-evm-6-yul-neicun-guanli-mstore-mload","掌握Yul中的EVM内存管理：空闲内存指针、手动ABI编码、构建外部调用数据以及内存高效模式。","## 空闲内存指针\n\n在Yul中操作内存时，理解Solidity的内存约定至关重要。0x40处的空闲内存指针追踪下一个可用的内存地址。\n\n```yul\nlet freePtr := mload(0x40)\nmstore(freePtr, someValue)\nmstore(0x40, add(freePtr, 0x20))  \u002F\u002F 推进指针\n```\n\n## mstore和mload操作码\n\n- **mstore(offset, value)** — 在给定偏移量写入32字节\n- **mload(offset)** — 从给定偏移量读取32字节\n- **mstore8(offset, value)** — 写入单个字节\n\n所有操作消耗3 gas加上潜在的内存扩展成本。\n\n## 手动ABI编码\n\n在Yul中为外部调用构建calldata是关键技能：\n\n```yul\n\u002F\u002F 编码 transfer(address,uint256) 调用\nmstore(0x00, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\nmstore(0x04, recipient)\nmstore(0x24, amount)\nlet success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n```\n\n## 内存扩展成本\n\n内存成本遵循二次增长公式。对于小内存使用（低于~700字节），成本近似线性。但增长快速：1 KB约98 gas，10 KB约1160 gas，1 MB约2,001,000 gas。\n\n## 外部调用数据构建\n\n从Yul进行外部调用需要手动在内存中构建calldata，执行调用，然后处理返回数据。\n\n## 内存高效模式\n\n1. **重用暂存空间（0x00-0x3f）** — 用于临时哈希和小型计算\n2. **不要不必要地扩展内存** — 每次扩展都有二次成本\n3. **对齐到32字节边界** — EVM以32字节块操作\n4. **在内存中打包数据** — 最小化内存占用\n\n## 总结\n\n内存管理是高效Yul编程的核心。理解空闲内存指针、手动ABI编码和内存扩展成本使你能够编写紧凑、gas高效的代码，超越Solidity编译器的能力。","\u003Ch2 id=\"\">空闲内存指针\u003C\u002Fh2>\n\u003Cp>在Yul中操作内存时，理解Solidity的内存约定至关重要。0x40处的空闲内存指针追踪下一个可用的内存地址。\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-yul\">let freePtr := mload(0x40)\nmstore(freePtr, someValue)\nmstore(0x40, add(freePtr, 0x20))  \u002F\u002F 推进指针\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"mstore-mload\">mstore和mload操作码\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>mstore(offset, value)\u003C\u002Fstrong> — 在给定偏移量写入32字节\u003C\u002Fli>\n\u003Cli>\u003Cstrong>mload(offset)\u003C\u002Fstrong> — 从给定偏移量读取32字节\u003C\u002Fli>\n\u003Cli>\u003Cstrong>mstore8(offset, value)\u003C\u002Fstrong> — 写入单个字节\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>所有操作消耗3 gas加上潜在的内存扩展成本。\u003C\u002Fp>\n\u003Ch2 id=\"abi\">手动ABI编码\u003C\u002Fh2>\n\u003Cp>在Yul中为外部调用构建calldata是关键技能：\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-yul\">\u002F\u002F 编码 transfer(address,uint256) 调用\nmstore(0x00, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\nmstore(0x04, recipient)\nmstore(0x24, amount)\nlet success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">内存扩展成本\u003C\u002Fh2>\n\u003Cp>内存成本遵循二次增长公式。对于小内存使用（低于~700字节），成本近似线性。但增长快速：1 KB约98 gas，10 KB约1160 gas，1 MB约2,001,000 gas。\u003C\u002Fp>\n\u003Ch2 id=\"\">外部调用数据构建\u003C\u002Fh2>\n\u003Cp>从Yul进行外部调用需要手动在内存中构建calldata，执行调用，然后处理返回数据。\u003C\u002Fp>\n\u003Ch2 id=\"\">内存高效模式\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\u003Cstrong>重用暂存空间（0x00-0x3f）\u003C\u002Fstrong> — 用于临时哈希和小型计算\u003C\u002Fli>\n\u003Cli>\u003Cstrong>不要不必要地扩展内存\u003C\u002Fstrong> — 每次扩展都有二次成本\u003C\u002Fli>\n\u003Cli>\u003Cstrong>对齐到32字节边界\u003C\u002Fstrong> — EVM以32字节块操作\u003C\u002Fli>\n\u003Cli>\u003Cstrong>在内存中打包数据\u003C\u002Fstrong> — 最小化内存占用\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">总结\u003C\u002Fh2>\n\u003Cp>内存管理是高效Yul编程的核心。理解空闲内存指针、手动ABI编码和内存扩展成本使你能够编写紧凑、gas高效的代码，超越Solidity编译器的能力。\u003C\u002Fp>\n","zh","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:25.884660Z","掌握Yul内存管理：空闲内存指针、手动ABI编码、calldata构建以及内存高效模式。","Yul内存管理",null,"index, follow",[21,26,30],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":31,"name":32,"slug":33,"created_at":25},"c0000000-0000-0000-0000-000000000018","Yul","yul","区块链",[36,42,48],{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":34,"published_at":41},"d0000000-0000-0000-0000-000000000599","Ethereum互操作层：55+个L2如何成为一条链","ethereum-hucaozuoceng-55-l2-chengwei-yitiao-lian","Ethereum有55+个Layer 2 rollup，碎片化了流动性和用户体验。Ethereum互操作层 — 结合跨rollup消息传递、共享排序器和based rollup — 旨在将它们统一为一个可组合的网络。","2026-03-28T10:44:44.539584Z",{"id":43,"title":44,"slug":45,"excerpt":46,"locale":12,"category_name":34,"published_at":47},"d0000000-0000-0000-0000-000000000598","ZK证明超越Rollups：Ethereum上的可验证AI推理","zk-zhengming-chaoyue-rollups-ethereum-keyanzheng-ai-tuili","零知识证明不再仅仅是扩容工具。在2026年，zkML实现了链上可验证的AI推理，ZK协处理器将繁重计算移至链下并在链上验证，而SP1和Jolt等新证明系统使其变得实用。","2026-03-28T10:44:44.534954Z",{"id":49,"title":50,"slug":51,"excerpt":52,"locale":12,"category_name":34,"published_at":53},"d0000000-0000-0000-0000-000000000575","EIP-7702实战：Pectra之后构建智能账户流程","eip-7702-shizhan-pectra-zhihou-goujian-zhineng-zhanghu-liucheng","EIP-7702允许任何Ethereum EOA在单笔交易中临时充当智能合约。以下是如何使用新的账户抽象原语实现批量交易、gas赞助和社交恢复。","2026-03-28T10:44:42.997040Z",{"id":13,"name":55,"slug":56,"bio":57,"photo_url":18,"linkedin":18,"role":58,"created_at":59,"updated_at":59},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]