關於 mload 操作碼的困惑
此程式碼用於返回函式輸入的 keccak256 並取自以下問題:
function assemblyKeccak (bytes memory _input) public pure returns (bytes32 x) { assembly { x := keccak256(add(_input, 0x20), mload(_input)) } }
我的問題是:
mload
操作碼通常獲取記憶體地址並載入儲存在那裡的內容(例如空閒記憶體指針 mload(0x40))。在這種情況下,它將字節作為輸入……它在這裡做什麼以及它正在載入什麼?
add
添加兩個輸入並返回結果。怎麼可能加上_input
32?
在彙編上下文中,您應該清楚地理解 2 點:
- 所有變數在彙編中都是值類型
彙編中沒有“引用類型”之類的東西,例如
_input
在彙編上下文中是字節數組的地址,而不是像純實體那樣的字節數組本身。考慮到作為地址(即指針)或其他任何值的值只是解釋問題,它絕不是由語言強制執行的。
- 記憶體陣列具有以下佈局
數組的長度儲存在它的地址(在這種情況下,值
_input
只是您將找到編碼為 32 字節的數組長度的地址),以下記憶體地址將包含多達 32 字節的數據必要的話。您可以在文件中閱讀有關它的更多資訊。
_input
對於直覺的解釋,如果數組由 33 個字節組成,每個字節都有 value ,這將是數組的實際記憶體佈局0x01
。所以 :
mload(_input)
載入包含在地址中的 32 字節值_input
(的值_input
是地址,的值是solidity 數組memory[_input]
的長度。)_input
add(_input, 0x20)
獲取地址_input
並添加 0x20 (32) 以跳過 32 字節長度欄位,結果是數據在記憶體中實際開始的地址。把它想像成 _input 的地址$$ 0 $$如果你想。
keccak256
( SHA3 ) 需要雜湊數據的偏移量和長度。偏移量只是數據開始的記憶體地址(add(_input, 0x20)
),它的長度mload(_input)
就像我們之前看到的那樣。我希望這能回答你的問題。如果有任何不清楚的地方,請毫不猶豫地詢問精確度。