Solidity

理解solidity內聯彙編程式碼

  • May 4, 2021

這是來自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 始終插入的數組邊界的成本。

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