Assembly
用mstore複製bytes32不行,為什麼?
為什麼不
mstore(c, p)
復製p
到c
?function test()returns (bytes32) { bytes32 c; bytes32 p = 0xFF; assembly { mstore(c, p) } return c; }
這裡的混淆可能是因為與傳統處理器不同,EVM 有幾個不同的“記憶體”通過不同的操作碼訪問:
- 通過
MSTORE
、MLOAD
、MSTORE8
和訪問的通用記憶體MLOAD8
。它用於儲存非原子資料結構,例如字元串、數組和結構。- 通過
PUSH*
,DUP*
,SWAP*
,訪問的堆棧記憶體POP
。它用於局部變數和參數以及內部呼叫方法的返回值。- 呼叫通過 、 和 訪問
CALLDATALOAD
的CALLDATASIZE
數據儲存器CALLDATACOPY
。該記憶體是只讀的,用於儲存外部呼叫方法的參數。- 返回通過
RETURNDATASIZE
,訪問的數據儲存器RETURNDATACOPY
。該記憶體也是只讀的,用於儲存由外部呼叫的方法返回的值。- 通過
CODESIZE
和訪問的程式碼儲存器CODECOPY
。也是只讀的,包含目前智能合約的字節碼。此記憶體也可用於部署時間常數,儘管此功能尚未在 Solidity 中實現。擁有如此多的記憶體使得很難將編譯器從類 C 語言創建到 EVM,因為在類 C 語言中,相同的指針可以引用任何變數,無論是本地的、動態的還是常量資源。
在您的範例
c
中,是在堆棧中分配的局部變數,因此無法通過MSTORE
. 您編寫的程式碼將 value ofc
視為一般記憶體中的地址,並將 value of 複製b
到該地址的記憶體槽中。
mstore 指令“將單詞保存到記憶體”。本質上,它儲存在地址 mu_s
$$ 0 $$(c的值)記憶體變數p的****值。因此,使用您的彙編指令,您將值 0xff 儲存在記憶體的地址 0 處。 問題是 c 沒有儲存在記憶體中(特別是沒有儲存在這個地址),而是儲存在 Stack 中(根據這個連結)。
所以要複製
p
in的值c
,你必須編寫這個彙編程式碼(我知道它不那麼酷,但它有效):assembly { c := p }