EVM汇编插入函数调用失效求助:执行停滞在pc 1923处
核心问题分析
DUP4指令触发栈下溢
执行到1920: DUP4时,栈的深度仅为3(经过1915、1917、1918三条指令后,栈中仅有3个元素),而DUPn指令要求栈至少包含n个元素才能复制第n个元素到栈顶。此时执行DUP4会直接触发栈下溢异常,导致EVM执行终止。你看到的"停滞在pc1923"大概率是调试工具的PC定位偏差,实际异常发生在DUP4指令执行时。CALL指令参数栈完全不符合EVM规范
EVM的CALL指令要求栈顶到栈底的参数顺序为:gas → to → value → argsOffset → argsLength → retOffset → retLength
你的指令序列压入的参数数量不足,顺序也完全错误,即便跳过栈下溢问题,CALL也无法正确解析参数执行调用。
修复步骤
修正DUP4指令:
确认使用DUP4的意图,如果是复制栈中第三个元素(栈深度为3时的最后一个元素),将DUP4改为DUP3;如果栈中确实需要4个元素,检查前面的指令是否遗漏了压栈操作,确保执行到该指令时栈深度≥4。重构CALL指令的参数栈:
以调用目标地址且不传递参数、不接收返回值为例,正确的汇编指令序列应如下(根据实际需求调整gas、参数等):; 压入CALL所需的7个参数(栈顶到栈底顺序) PUSH2 0xc350 ; 1. gas 调用函数b所需的gas值 PUSH20 0x2fd82b67cba721f941e784c67aeb0f938aede2c8 ; 2. to 函数b所在合约地址 PUSH1 0x00 ; 3. value 调用时传递的ETH数量(0表示不传递) PUSH1 0x00 ; 4. argsOffset 调用参数在内存中的起始偏移(0表示无参数) PUSH1 0x00 ; 5. argsLength 调用参数的长度(0表示无参数) PUSH1 0x00 ; 6. retOffset 存储返回值的内存起始偏移(0表示不接收返回值) PUSH1 0x00 ; 7. retLength 存储返回值的内存长度(0表示不接收返回值) CALL ; 执行调用验证栈状态与指令执行:
使用支持逐步栈跟踪的EVM调试工具(如Hardhat的--verbose跟踪模式),查看每一条指令执行后的栈变化,确认异常发生的准确位置,确保所有指令执行时栈深度符合要求。确认目标地址有效性:
检查0x2fd82b67cba721f941e784c67aeb0f938aede2c8是否为正确的合约地址,且该合约未被销毁,函数b的入口逻辑正常。
内容的提问来源于stack exchange,提问作者pypy233

