Assembly
在彙編中操作單個字節
我正在學習彙編,我正在嘗試寫給數組
bytes
中的個人。bytes32
我有以下程式碼:contract TestAssembly {} function test( uint8 _count ) public { bytes32 bytesTest; assembly { for { let i := 0} lt(i, _count) { i := add(i, 1) } { mstore(add(bytesTest, i), 0x33) } } } }
我希望這段程式碼會遍歷 中的每個字節
bytesTest
,並將每個字節替換為0x33
,但bytesTest
似乎沒有被修改。
在@Jesbus 評論的基礎上,這裡是一個實現你想要的評論範例:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract TestAssembly { function test(uint8 _count) public pure returns (bytes memory) { // Declares the array in memory bytes memory bytesTest = new bytes(10); // Protect against buffer overflow require(_count <= 10, "not enough bytes in the array"); assembly { // Skip the first 32 bytes reserved for the length of the memory array let offset := add(bytesTest, 0x20) // Loop _count times over the array for { let i := 0} lt(i, _count) { i := add(i, 1) } { // Make use of mstore8 (1 byte) instead of mstore (32 bytes) mstore8(add(offset, i), 0x33) } } return bytesTest; } }
編輯:
我正在添加一個依賴於沒有長度前綴並使用 bytes32 的數組文字的範例。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract TestAssembly { function test(uint8 _count) public pure returns (bytes32) { // Declares the byte32 array in memory : this is an array literal -> there is no length prefix bytes32[1] memory bytesTest = [bytes32(0)]; // Protect against buffer overflow require(_count <= 32, "not enough bytes in the array"); assembly { // Loop _count times over the array for { let i := 0} lt(i, _count) { i := add(i, 1) } { // Make use of mstore8 (1 byte) instead of mstore (32 bytes) mstore8(add(bytesTest, i), 0x33) } } return bytesTest[0]; } }
再加上第三個例子,它不依賴於solidity數組,而是通過彙編直接在記憶體中分配/計算。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract TestAssembly { function test(uint8 _count) public pure returns (bytes32) { bytes32 result; // Protect against buffer overflow require(_count <= 32, "not enough bytes in the array"); assembly { // Allocate 32 bytes from the free memory pointer let buffer := mload(0x40) // Increase the free memory pointer to account for our buffer mstore(0x40, add(buffer, 0x20)) // Loop _count times over the array for { let i := 0} lt(i, _count) { i := add(i, 1) } { // Make use of mstore8 (1 byte) instead of mstore (32 bytes) mstore8(add(buffer, i), 0x33) } result := mload(buffer) // Decrease the free memory pointer to account for our buffer mstore(0x40, sub(buffer, 0x20)) } return result; } }