Assembly

這個彙編程式碼如何創建一個新的“記憶體端”?

  • August 31, 2021

文件

mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))

語境:

library GetCode {
   function at(address _addr) public view returns (bytes memory o_code) {
       assembly {
           // retrieve the size of the code, this needs assembly
           let size := extcodesize(_addr)
           // allocate output byte array - this could also be done without assembly
           // by using o_code = new bytes(size)
           o_code := mload(0x40)
           // new "memory end" including padding
           mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
           // ...
       }
   }
}

我可以按照運算符解析十六進制,但是我不確定是否應該對基礎值或記憶體地址值本身執行這些操作(例如 0x20 + 0x40 = 0x60)。

它稍後在同一文件中進行了解釋:

Solidity 以一種非常簡單的方式管理記憶體:在記憶體中的 0x40 位置有一個“空閒記憶體指針”。如果要分配記憶體,只需使用從該指針指向的位置開始的記憶體並相應地更新它。

數組總是使用第一個槽來儲存它的長度,並且總是對齊到 32 個字節(一個槽)。

在虛擬碼中,它執行如下操作:

  • 讀取空閒記憶體指針
array_memory = memory[0x40]
  • 計算記憶體中的數組大小,為數組長度添加額外的 32 字節並將其四捨五入為 32 字節。數學公式是trunc((code_size + 32 + 32 - 1) / 32) * 32。並針對 EVM 組裝進行了優化
array_size = (code_size + 0x20 + 0x1f) & ~0x1f
  • 更新空閒記憶體指針
memory[0x40] += array_size

引用自:https://ethereum.stackexchange.com/questions/70839