0

I'm try to understand each opcode defined in Ethereum Virtual Machine. As for the opcode 'CALL' I find that it needs 7 arguments from the stack: gas, addr, value, argument addr, argument offset, return addr and return offset. My question is that, how the evm determine the return addr and offset for a CALL opcode. When I try my own contract on Remix, I found that the return address is always the same as the argument address before a CALL opcode. Is that always true? Or this is just some kind of coincidence?

// this is my contract code:
contract Demo1{
    uint public goal = 2000;
    function getGoal() public returns(uint){
        return goal;
    }
}
contract Demo2{
    function test2(Demo1 demo1, uint b) public returns (uint){
        uint goal_ = demo1.getGoal();
        if(b < goal_){
            b += goal_;
        }
        return b;
    }
}

And when I use Reimx to debug the function test2, I stop before the CALL opcode and the stack loos like this:

0: 0x00000000000000000000000000000000000000000000000000000000002d6963
1: 0x0000000000000000000000000de37dce8154ce54d895bd16942c86d568ddb5fc
2: 0x0000000000000000000000000000000000000000000000000000000000000000
3: 0x0000000000000000000000000000000000000000000000000000000000000080
4: 0x0000000000000000000000000000000000000000000000000000000000000004
5: 0x0000000000000000000000000000000000000000000000000000000000000080
6: 0x0000000000000000000000000000000000000000000000000000000000000020
...
0

Actually the return address is a pointer to memory where the returned value should be stored, and the return offset is instead the maximum size of memory that can be written.

In the example the function getGoal returns an uint so the contract has to reserve 32 bytes for the return value (0x20) and it appears that 0x80 is the first address of unused memory. The compiler seems to generate the code such that the input will not be used after CALL and the same address can be reused to store the returned value.

When the returned data is of variable size, you can pass 0 for both the return address and the return size. Then you can access the returned data with RETURNDATASIZE and RETURNDATACOPY.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.