Solidity
理解solidity內聯彙編程式碼
這是來自solidity文件的程式碼:
function sumAsm(uint[] _data) public returns (uint o_sum) { for (uint i = 0; i < _data.length; ++i) { assembly { o_sum := add(o_sum, mload(add(add(_data, 0x20), mul(i, 0x20)))) } } }
任何人都可以解釋這段程式碼。_data 是一個 uint 數組。我們如何將 0x20 添加到數組中。如果數組名稱代表第一個元素的地址,為什麼我們要偏移它?這一行如何
(add(add(_data, 0x20), mul(i, 0x20)))
給出數組的第一個和後續元素的地址。
在彙編程式碼中,
_data
是數組數據開始的記憶體地址。但是,第一個記憶體字(32 字節 = 0x20 字節)是為數組的長度保留的,所以我們需要跳過它。因此,
_data[0]
位於記憶體地址_data + 0x20
。在程式碼中,這看起來像add(_data, 0x20)
.數組元素從 0 開始連續編號,每個元素佔用一個 32 字節(0x20 字節)字。因此,元素
$$ N $$從我們上面找到的數組數據的開頭偏移 N * 0x20。在程式碼中,這個偏移量是
mul(i, 0x20)
. 將它們放在一起,_data[i]
可以在 處找到(_data + 0x20) + (i * 0x20)
,即表達式(add(add(_data, 0x20), mul(i, 0x20)))
。循環的最終效果是將所有數組元素添加到
o_sum
. 它可能在彙編中完成,以避免檢查 Solidity 始終插入的數組邊界的成本。