This trivial contract:
contract Test {
function test() returns (string) {
return "foobar";
}
}
Results in assembly code output (in the solidity web compiler) for the function 'test' that looks like this:
tag 2 function test() returns (strin...
JUMPDEST function test() returns (strin...
PUSH 0 contract Test {\n function ...
PUSH 60 contract Test {\n function ...
MSTORE string
PUSH C0 return "foobar"
PUSH 40 contract Test {\n function ...
MSTORE return "foobar"
PUSH 6 return "foobar"
PUSH 80 string
SWAP1 return "foobar"
DUP2 return "foobar"
MSTORE return "foobar"
PUSH 666F6F6261720000000000000000000000000000000000000000000000000000 return "foobar"
PUSH A0 return "foobar"
MSTORE return "foobar"
PUSH 20 string
PUSH C0 return "foobar"
SWAP1 function test() returns (strin...
DUP2 function test() returns (strin...
MSTORE function test() returns (strin...
PUSH 6 return "foobar"
PUSH E0 function test() returns (strin...
DUP2 function test() returns (strin...
SWAP1 function test() returns (strin...
MSTORE function test() returns (strin...
DUP2 return "foobar"
SWAP1 return "foobar"
PUSH 100 function test() returns (strin...
SWAP1 function test() returns (strin...
PUSH A0 return "foobar"
SWAP1 return "foobar"
DUP1 return "foobar"
DUP4 function test() returns (strin...
DUP2 return "foobar"
DUP5 return "foobar"
PUSH 0 contract Test {\n function ...
PUSH 4 function test() returns (strin...
PUSH 12 function test() returns (strin...
CALL function test() returns (strin...
POP
POP
DUP2 function test() returns (strin...
MLOAD function test() returns (strin...
PUSH FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
NOT
AND function test() returns (strin...
SWAP1 function test() returns (strin...
SWAP2 function test() returns (strin...
MSTORE function test() returns (strin...
POP
POP
PUSH 40 contract Test {\n function ...
MLOAD function test() returns (strin...
PUSH 120 function test() returns (strin...
DUP2 function test() returns (strin...
SWAP1 function test() returns (strin...
SUB function test() returns (strin...
SWAP3 function test() returns (strin...
POP
SWAP1 function test() returns (strin...
POP
RETURN
I can see the hex version of the string, and its length, being written to memory fairly early on. Then it does a whole lot of weird stuff, and issues a CALL with very little gas to address '4', as far as I can tell. The Ethereum yellowpaper says that the contract at address 4 implements the identity function, which seems an entirely pointless thing to call in this context.
Why is it doing this for what looks like a very straightforward 'return'?