1

Simple example:

Let's say I have a function that takes a fixed size array, finds the largest number in it, and returns another fixed size array in memory with the largest number as the last index:

function sortFixedArray(uint256[6] memory array) public pure returns 
         (uint256[6] memory sortedArray) {
    
    sortedArray = array; // duplicate parameter array in memory
    uint ceiling;
    uint last;
    uint highIndex;

    for (uint i = 0; i < 6;) {
        last = sortedArray[5];
       
        if (sortedArray[i] > 1 && sortedArray[i] > ceiling) {
            ceiling = sortedArray[i];
            highIndex = i;
        }
        unchecked { i++; }
    }
    sortedArray[5] = ceiling;
    if (highIndex < 5) {
        sortedArray[highIndex] = last;
    }
    sortedArray[5] = ceiling;
    ceiling = 0;

    return sortedArray;
}

As you can see, I am checking the index values of the array with a for loop and sortedArray[i]. But assembly doesn't recognize sortedArray[i], so how would I access each index's value?

1 Answer 1

0

Since sortedArray is an object in memory you have to use mload to read the value.

In assembly a fixed-size array points at the first element of the array, so mload(sortedArray) will read the first element.

sortedArray[i] is i slots down in memory, where each slot is 32 bytes (0x20 in hex). So the memory position of this element is sortedArray + 32*i. In assembly:

mload(add(sortedArray, mul(0x20, i)))

This is the whole function using inline assembly:

    function sortFixedArrayAssembly(uint256[6] memory array) public pure returns (uint256[6] memory sortedArray) {
        sortedArray = array; // duplicate parameter array in memory
        assembly {
            let last := mload(add(sortedArray, mul(0x20, 5)))
            let highIndex := 0
            let ceiling := 0

            for { let i := 0 } lt(i, 6) { i := add(i, 1) } {
                let i_elem := mload(add(sortedArray, mul(0x20, i)))
                if and(gt(i_elem, 1), gt(i_elem, ceiling)) {
                    ceiling := i_elem
                    highIndex := i
                }
            }

            mstore(add(sortedArray, mul(0x20, 5)), ceiling)
            if lt(highIndex, 5) {
                mstore(add(sortedArray, mul(0x20, highIndex)), last)
            }
        }
        return sortedArray;
    }
1
  • 1
    You're a wizard! This works, thank you. Learned a lot and now I can apply this to so many things.
    – EKN
    Dec 12, 2022 at 18:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.