Code has been added to clipboard!

Solidity Inline Assembly Example 2

Example
pragma solidity ^0.4.12;

library SumVector {
    // The function presented here is not as efficient, as the optimizer
    // fails at removing the bounds checks at array access.
    function SoliditySum(uint[] _sumData) returns (uint o_dataSum) {
        for (uint n = 0; n < _sumData.length; ++n)
            o_dataSum += _sumData[n];
    }

    // Now we are aware that we may only access arrays that are in bounds, so 
    // the check can be avoided. 0x20 would need to be added to the array since 
    // the first slot is meant to contain the length of the array.
    function asmSum(uint[] _sumData) returns (uint o_dataSum) {
        for (uint n = 0; n < _sumData.length; ++n) {
            assembly {
                o_dataSum := add(o_dataSum, mload(add(add(_sumData, 0x20), mul(n, 0x20))))
            }
        }
    }

    // The code below does the same as above only using inline assembly
    function asmPureSum(uint[] _sumData) returns (uint o_dataSum) {
        assembly {
           // The length is loaded (first 32 bytes)
           let len := mload(_sumData)

           // The length field is skipepd over.
           //
           // A temporary variable is kept to it can be incremented in place.
           //
           // NOTE: if _sumData were to be incremented, it would result in
           //       an unusable _sumData variable after that block of assembly
           let letData := add(_sumData, 0x20)

           // Iterating to the point the bound is not met.
           for
               { let end := add(letData, len) }
               lt(letData, end)
               { letData := add(letData, 0x20) }
           {
               o_dataSum := add(o_dataSum, mload(letData))
           }
        }
    }
}