Appearance
Fibonacci
IMPORTANT
The examples are designed to be run in order after completing the quickstart, which will help you set up your environment and get familiar with common commands.
If you are just here to browse, enjoy!
🔢 Fibonacci sequence background
The Fibonacci sequence is a classic mathematical sequence where each number is the sum of the two preceding ones, typically starting with
The Fibonacci program takes a single byte of instruction data representing the sequence index u32 values back to the caller.
🛡️ Input validation
Like the memo example, the program first validates that no accounts are passed by checking the number of accounts in the input buffer:
asm
.equ NUM_ACCOUNTS_OFFSET, 0
.equ INSTRUCTION_DATA_LENGTH_OFFSET, 8
.equ INSTRUCTION_DATA_OFFSET, 16
.equ E_ACCOUNTS, 0xffffffff
.equ E_MAX_N, 0xfffffffe
.equ MAX_N, 47
.equ MAX_N_SPECIAL_CASE, 1
.global entrypoint
entrypoint:
# Indexed load double word the number of accounts into r3, for use as a
# scratch register.
ldxdw r3, [r1 + NUM_ACCOUNTS_OFFSET]
# If number of accounts is nonzero, jump to abort_accounts. Note r4
# initially contains zero.
jne r3, r4, abort_accountsIf accounts are detected, the program immediately exits with error code E_ACCOUNTS (0xffffffff):
asm
abort_accounts:
mov32 r0, E_ACCOUNTS
exitFull program
asm
.equ NUM_ACCOUNTS_OFFSET, 0
.equ INSTRUCTION_DATA_LENGTH_OFFSET, 8
.equ INSTRUCTION_DATA_OFFSET, 16
.equ E_ACCOUNTS, 0xffffffff
.equ E_MAX_N, 0xfffffffe
.equ MAX_N, 47
.equ MAX_N_SPECIAL_CASE, 1
.global entrypoint
entrypoint:
# Indexed load double word the number of accounts into r3, for use as a
# scratch register.
ldxdw r3, [r1 + NUM_ACCOUNTS_OFFSET]
# If number of accounts is nonzero, jump to abort_accounts. Note r4
# initially contains zero.
jne r3, r4, abort_accounts
# Indexed load single byte the sequence number into r8. Only check a single
# byte since MAX_N < 256.
ldxb r8, [r1 + INSTRUCTION_DATA_OFFSET]
# If sequence number > MAX_N, jump to exit with error code E_MAX_N.
jgt r8, MAX_N, abort_max_n
# Prepare call-preserved registers for loop. Since r6 defaults to 0:
# {r6 = F(0) = 0, r7 = F(1) = 1}
mov64 r7, 1
# F(n) = n for n = {0, 1}. So compare sequence number to
# MAX_N_SPECIAL_CASE then loop if not special case.
jgt r8, MAX_N_SPECIAL_CASE, loop
mov64 r0, r8
exit
loop:
# Decrement sequence number tracker for iteration. Using r9 as a scratch
# register, increment the sequence numbers of the two Fibonacci numbers
# being tracked. For example on the first iteration,
# {r6 = F(0), r7 = F(1)} -> {r6 = F(1), r7 = F(2)}
mov64 r9, r6
mov64 r6, r7
add64 r7, r9
# Decrement sequence number counter.
sub32 r8, 1
# If sequence number counter > 1, continue loop.
jgt r8, MAX_N_SPECIAL_CASE, loop
# Now result in r7 = F(n), move into return code register.
mov64 r0, r7
exit
abort_accounts:
mov32 r0, E_ACCOUNTS
exit
abort_max_n:
mov32 r0, E_MAX_N
exitNext, the program validates that the requested Fibonacci index MAX_N (47), which is the largest index whose Fibonacci number fits in a u32 while leaving room for two error codes:
asm
.equ NUM_ACCOUNTS_OFFSET, 0
.equ INSTRUCTION_DATA_LENGTH_OFFSET, 8
.equ INSTRUCTION_DATA_OFFSET, 16
.equ E_ACCOUNTS, 0xffffffff
.equ E_MAX_N, 0xfffffffe
.equ MAX_N, 47
.equ MAX_N_SPECIAL_CASE, 1asm
entrypoint:
# Indexed load double word the number of accounts into r3, for use as a
# scratch register.
ldxdw r3, [r1 + NUM_ACCOUNTS_OFFSET]
# If number of accounts is nonzero, jump to abort_accounts. Note r4
# initially contains zero.
jne r3, r4, abort_accounts
# Indexed load single byte the sequence number into r8. Only check a single
# byte since MAX_N < 256.
ldxb r8, [r1 + INSTRUCTION_DATA_OFFSET]
# If sequence number > MAX_N, jump to exit with error code E_MAX_N.
jgt r8, MAX_N, abort_max_ntest_max_fib_u32
rust
#[test]
fn test_max_fib_u32() {
assert!(fib(MAX_FIB_INDEX_U32) <= E_INDEX_TOO_BIG.into());
assert!(fib(MAX_FIB_INDEX_U32 + 1) > u32::MAX.into());
}If the index is too large, the program exits with error code E_MAX_N (0xfffffffe).
asm
abort_max_n:
mov32 r0, E_MAX_N
exitFull program
asm
.equ NUM_ACCOUNTS_OFFSET, 0
.equ INSTRUCTION_DATA_LENGTH_OFFSET, 8
.equ INSTRUCTION_DATA_OFFSET, 16
.equ E_ACCOUNTS, 0xffffffff
.equ E_MAX_N, 0xfffffffe
.equ MAX_N, 47
.equ MAX_N_SPECIAL_CASE, 1
.global entrypoint
entrypoint:
# Indexed load double word the number of accounts into r3, for use as a
# scratch register.
ldxdw r3, [r1 + NUM_ACCOUNTS_OFFSET]
# If number of accounts is nonzero, jump to abort_accounts. Note r4
# initially contains zero.
jne r3, r4, abort_accounts
# Indexed load single byte the sequence number into r8. Only check a single
# byte since MAX_N < 256.
ldxb r8, [r1 + INSTRUCTION_DATA_OFFSET]
# If sequence number > MAX_N, jump to exit with error code E_MAX_N.
jgt r8, MAX_N, abort_max_n
# Prepare call-preserved registers for loop. Since r6 defaults to 0:
# {r6 = F(0) = 0, r7 = F(1) = 1}
mov64 r7, 1
# F(n) = n for n = {0, 1}. So compare sequence number to
# MAX_N_SPECIAL_CASE then loop if not special case.
jgt r8, MAX_N_SPECIAL_CASE, loop
mov64 r0, r8
exit
loop:
# Decrement sequence number tracker for iteration. Using r9 as a scratch
# register, increment the sequence numbers of the two Fibonacci numbers
# being tracked. For example on the first iteration,
# {r6 = F(0), r7 = F(1)} -> {r6 = F(1), r7 = F(2)}
mov64 r9, r6
mov64 r6, r7
add64 r7, r9
# Decrement sequence number counter.
sub32 r8, 1
# If sequence number counter > 1, continue loop.
jgt r8, MAX_N_SPECIAL_CASE, loop
# Now result in r7 = F(n), move into return code register.
mov64 r0, r7
exit
abort_accounts:
mov32 r0, E_ACCOUNTS
exit
abort_max_n:
mov32 r0, E_MAX_N
exit🔁 Fibonacci computation loop
The algorithm uses three registers to compute Fibonacci numbers iteratively:
r6:: initialized to 0 r7:: initialized to 1 r8: Loop counter, decremented fromto 1
These registers (r6, r7, r8) are call-preserved (callee-saved/non-volatile) registers in the SBPF calling convention, meaning their values are preserved across function calls. This makes them ideal for storing loop state that needs to persist across iterations.
TIP
This example does not implement call so the call-preserved property isn't strictly needed. However, using call-preserved registers is a good practice for maintaining state across function calls in more complex programs.
The program handles the special cases
asm
.equ NUM_ACCOUNTS_OFFSET, 0
.equ INSTRUCTION_DATA_LENGTH_OFFSET, 8
.equ INSTRUCTION_DATA_OFFSET, 16
.equ E_ACCOUNTS, 0xffffffff
.equ E_MAX_N, 0xfffffffe
.equ MAX_N, 47
.equ MAX_N_SPECIAL_CASE, 1asm
# Indexed load single byte the sequence number into r8. Only check a single
# byte since MAX_N < 256.
ldxb r8, [r1 + INSTRUCTION_DATA_OFFSET]
# If sequence number > MAX_N, jump to exit with error code E_MAX_N.
jgt r8, MAX_N, abort_max_n
# Prepare call-preserved registers for loop. Since r6 defaults to 0:
# {r6 = F(0) = 0, r7 = F(1) = 1}
mov64 r7, 1
# F(n) = n for n = {0, 1}. So compare sequence number to
# MAX_N_SPECIAL_CASE then loop if not special case.
jgt r8, MAX_N_SPECIAL_CASE, loop
mov64 r0, r8
exitFor
asm
# F(n) = n for n = {0, 1}. So compare sequence number to
# MAX_N_SPECIAL_CASE then loop if not special case.
jgt r8, MAX_N_SPECIAL_CASE, loop
mov64 r0, r8
exit
loop:
# Decrement sequence number tracker for iteration. Using r9 as a scratch
# register, increment the sequence numbers of the two Fibonacci numbers
# being tracked. For example on the first iteration,
# {r6 = F(0), r7 = F(1)} -> {r6 = F(1), r7 = F(2)}
mov64 r9, r6
mov64 r6, r7
add64 r7, r9
# Decrement sequence number counter.
sub32 r8, 1
# If sequence number counter > 1, continue loop.
jgt r8, MAX_N_SPECIAL_CASE, loop
# Now result in r7 = F(n), move into return code register.
mov64 r0, r7
exitEach iteration performs the following:
- Save
from r6into scratch registerr9. - Move
from r7tor6, making it the new. - Add the old
from r9tor7, computing. - Decrement the loop counter in
r8. - Return if the counter is still greater than 1.
Full program
asm
.equ NUM_ACCOUNTS_OFFSET, 0
.equ INSTRUCTION_DATA_LENGTH_OFFSET, 8
.equ INSTRUCTION_DATA_OFFSET, 16
.equ E_ACCOUNTS, 0xffffffff
.equ E_MAX_N, 0xfffffffe
.equ MAX_N, 47
.equ MAX_N_SPECIAL_CASE, 1
.global entrypoint
entrypoint:
# Indexed load double word the number of accounts into r3, for use as a
# scratch register.
ldxdw r3, [r1 + NUM_ACCOUNTS_OFFSET]
# If number of accounts is nonzero, jump to abort_accounts. Note r4
# initially contains zero.
jne r3, r4, abort_accounts
# Indexed load single byte the sequence number into r8. Only check a single
# byte since MAX_N < 256.
ldxb r8, [r1 + INSTRUCTION_DATA_OFFSET]
# If sequence number > MAX_N, jump to exit with error code E_MAX_N.
jgt r8, MAX_N, abort_max_n
# Prepare call-preserved registers for loop. Since r6 defaults to 0:
# {r6 = F(0) = 0, r7 = F(1) = 1}
mov64 r7, 1
# F(n) = n for n = {0, 1}. So compare sequence number to
# MAX_N_SPECIAL_CASE then loop if not special case.
jgt r8, MAX_N_SPECIAL_CASE, loop
mov64 r0, r8
exit
loop:
# Decrement sequence number tracker for iteration. Using r9 as a scratch
# register, increment the sequence numbers of the two Fibonacci numbers
# being tracked. For example on the first iteration,
# {r6 = F(0), r7 = F(1)} -> {r6 = F(1), r7 = F(2)}
mov64 r9, r6
mov64 r6, r7
add64 r7, r9
# Decrement sequence number counter.
sub32 r8, 1
# If sequence number counter > 1, continue loop.
jgt r8, MAX_N_SPECIAL_CASE, loop
# Now result in r7 = F(n), move into return code register.
mov64 r0, r7
exit
abort_accounts:
mov32 r0, E_ACCOUNTS
exit
abort_max_n:
mov32 r0, E_MAX_N
exit📈 Compute unit consumption
The assembly implementation demonstrates
test_asm
rs
#[test]
fn test_asm() {
test_fibonacci_program(ProgramLanguage::Assembly, true);
}Test results
sh
Fibonacci numbers and compute units:
F(0): 0 (Compute Units: 8)
F(1): 1 (Compute Units: 8)
F(2): 1 (Compute Units: 13)
F(3): 2 (Compute Units: 18)
F(4): 3 (Compute Units: 23)
F(5): 5 (Compute Units: 28)
F(6): 8 (Compute Units: 33)
F(7): 13 (Compute Units: 38)
F(8): 21 (Compute Units: 43)
F(9): 34 (Compute Units: 48)
F(10): 55 (Compute Units: 53)
F(11): 89 (Compute Units: 58)
F(12): 144 (Compute Units: 63)
F(13): 233 (Compute Units: 68)
F(14): 377 (Compute Units: 73)
F(15): 610 (Compute Units: 78)
F(16): 987 (Compute Units: 83)
F(17): 1597 (Compute Units: 88)
F(18): 2584 (Compute Units: 93)
F(19): 4181 (Compute Units: 98)
F(20): 6765 (Compute Units: 103)
F(21): 10946 (Compute Units: 108)
F(22): 17711 (Compute Units: 113)
F(23): 28657 (Compute Units: 118)
F(24): 46368 (Compute Units: 123)
F(25): 75025 (Compute Units: 128)
F(26): 121393 (Compute Units: 133)
F(27): 196418 (Compute Units: 138)
F(28): 317811 (Compute Units: 143)
F(29): 514229 (Compute Units: 148)
F(30): 832040 (Compute Units: 153)
F(31): 1346269 (Compute Units: 158)
F(32): 2178309 (Compute Units: 163)
F(33): 3524578 (Compute Units: 168)
F(34): 5702887 (Compute Units: 173)
F(35): 9227465 (Compute Units: 178)
F(36): 14930352 (Compute Units: 183)
F(37): 24157817 (Compute Units: 188)
F(38): 39088169 (Compute Units: 193)
F(39): 63245986 (Compute Units: 198)
F(40): 102334155 (Compute Units: 203)
F(41): 165580141 (Compute Units: 208)
F(42): 267914296 (Compute Units: 213)
F(43): 433494437 (Compute Units: 218)
F(44): 701408733 (Compute Units: 223)
F(45): 1134903170 (Compute Units: 228)
F(46): 1836311903 (Compute Units: 233)
F(47): 2971215073 (Compute Units: 238)
test tests::test_asm ... ok
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 4 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xffffffff
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 6 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xfffffffe
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 8 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... success
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 8 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 13 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 18 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x2
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 23 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x3
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 28 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x5
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 33 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x8
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 38 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xd
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 43 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x15
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 48 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x22
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 53 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x37
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 58 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x59
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 63 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x90
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 68 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xe9
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 73 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x179
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 78 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x262
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 83 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x3db
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 88 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x63d
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 93 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xa18
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 98 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1055
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 103 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1a6d
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 108 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x2ac2
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 113 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x452f
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 118 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x6ff1
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 123 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xb520
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 128 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x12511
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 133 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1da31
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 138 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x2ff42
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 143 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x4d973
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 148 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x7d8b5
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 153 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xcb228
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 158 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x148add
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 163 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x213d05
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 168 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x35c7e2
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 173 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x5704e7
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 178 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x8cccc9
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 183 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xe3d1b0
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 188 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1709e79
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 193 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x2547029
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 198 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x3c50ea2
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 203 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x6197ecb
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 208 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x9de8d6d
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 213 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xff80c38
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 218 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x19d699a5
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 223 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x29cea5dd
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 228 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x43a53f82
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 233 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x6d73e55f
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 238 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xb11924e1🦀 Rust implementation
The Rust implementation mirrors the assembly logic but uses a function to encapsulate the Fibonacci computation, which is written specifically to produce a comparable assembly loop output:
rs
use pinocchio::{entrypoint, error::ProgramError, AccountView, Address, ProgramResult};
const E_MAX_N: u32 = 0xfffffffe;
const MAX_N: u8 = 47;
const MAX_N_SPECIAL_CASE: u8 = 1;
entrypoint!(process_instruction);
#[cfg_attr(not(target_os = "solana"), allow(unused_variables))]
fn process_instruction(
_program_id: &Address,
_accounts: &[AccountView],
instruction_data: &[u8],
) -> ProgramResult {
let n = instruction_data[0];
match n {
0 => Ok(()),
MAX_N_SPECIAL_CASE => Err(ProgramError::Custom(MAX_N_SPECIAL_CASE as u32)),
n if n > MAX_N => Err(ProgramError::Custom(E_MAX_N)),
_ => Err(ProgramError::Custom(fib(n as u64))),
}
}
// If r8 is a u8 the compiler generates an extra opcode to cast it to u8.
fn fib(mut r8: u64) -> u32 {
let mut r6: u32 = 0;
let mut r7: u32 = 1;
loop {
let r9 = r6;
r6 = r7;
unsafe {
r7 = r7.unchecked_add(r9);
r8 = r8.unchecked_sub(1);
};
if r8 == 1 {
return r7;
};
}
}Note that unlike the assembly version, the Rust implementation doesn't check for the number of passed accounts because Pinocchio's entrypoint! macro by default handles account parsing automatically, including specifying a maximum number of accounts, past which any extra accounts are ignored.
rs-disassembly.s (core Fibonacci logic highlighted)
asm
.globl entrypoint
entrypoint:
add64 r10, -2048
mov64 r2, r1
add64 r2, 8
ldxdw r3, [r1+0]
jeq r3, 0, jmp_00a0
stxdw [r10+16], r2
ldxdw r2, [r1+88]
add64 r1, r2
add64 r1, 10351
and64 r1, -8
jeq r3, 1, jmp_00a8
jne r3, 2, jmp_0150
ldxb r2, [r1+0]
jne r2, 255, jmp_0610
stxdw [r10+24], r1
jmp_0078:
ldxdw r2, [r1+80]
add64 r1, r2
add64 r1, 10343
and64 r1, -8
ja jmp_00a8
jmp_00a0:
mov64 r1, r2
jmp_00a8:
ldxdw r2, [r1+0]
jeq r2, 0, jmp_08e0
ldxb r1, [r1+8]
jeq r1, 0, jmp_00e0
jne r1, 1, jmp_00f0
mov64 r0, 1
ja jmp_0148
jmp_00e0:
mov64 r0, r1
ja jmp_0148
jmp_00f0:
mov32 r0, -2
jgt r1, 47, jmp_0148
mov32 r2, 1
mov32 r3, 0
add64 r1, -1
mov32 r0, 1
jmp_0120:
add32 r0, r3
add64 r1, -1
mov64 r3, r2
mov64 r2, r0
jne r1, 0, jmp_0120
jmp_0148:
exit
jmp_0150:
mov64 r2, r10
add64 r2, 16
jlt r3, 6, jmp_0420
mov64 r2, r10
add64 r2, 16
jmp_0178:
ldxb r4, [r1+0]
jne r4, 255, jmp_02b0
stxdw [r2+8], r1
ldxdw r4, [r1+80]
add64 r1, r4
add64 r1, 10343
and64 r1, -8
ldxb r4, [r1+0]
jne r4, 255, jmp_02f8
jmp_01c0:
stxdw [r2+16], r1
ldxdw r4, [r1+80]
add64 r1, r4
add64 r1, 10343
and64 r1, -8
ldxb r4, [r1+0]
jne r4, 255, jmp_0340
jmp_01f8:
stxdw [r2+24], r1
ldxdw r4, [r1+80]
add64 r1, r4
add64 r1, 10343
and64 r1, -8
ldxb r4, [r1+0]
jne r4, 255, jmp_0388
jmp_0230:
stxdw [r2+32], r1
ldxdw r4, [r1+80]
add64 r1, r4
add64 r1, 10343
and64 r1, -8
add64 r2, 40
ldxb r4, [r1+0]
jne r4, 255, jmp_03d8
jmp_0270:
stxdw [r2+0], r1
ldxdw r4, [r1+80]
add64 r1, r4
add64 r1, 10343
and64 r1, -8
add64 r3, -5
jgt r3, 5, jmp_0178
ja jmp_0420
jmp_02b0:
lsh64 r4, 3
mov64 r5, r10
add64 r5, 16
add64 r5, r4
ldxdw r4, [r5+0]
stxdw [r2+8], r4
add64 r1, 8
ldxb r4, [r1+0]
jeq r4, 255, jmp_01c0
jmp_02f8:
lsh64 r4, 3
mov64 r5, r10
add64 r5, 16
add64 r5, r4
ldxdw r4, [r5+0]
stxdw [r2+16], r4
add64 r1, 8
ldxb r4, [r1+0]
jeq r4, 255, jmp_01f8
jmp_0340:
lsh64 r4, 3
mov64 r5, r10
add64 r5, 16
add64 r5, r4
ldxdw r4, [r5+0]
stxdw [r2+24], r4
add64 r1, 8
ldxb r4, [r1+0]
jeq r4, 255, jmp_0230
jmp_0388:
lsh64 r4, 3
mov64 r5, r10
add64 r5, 16
add64 r5, r4
ldxdw r4, [r5+0]
stxdw [r2+32], r4
add64 r1, 8
add64 r2, 40
ldxb r4, [r1+0]
jeq r4, 255, jmp_0270
jmp_03d8:
lsh64 r4, 3
mov64 r5, r10
add64 r5, 16
add64 r5, r4
ldxdw r4, [r5+0]
stxdw [r2+0], r4
add64 r1, 8
add64 r3, -5
jgt r3, 5, jmp_0178
jmp_0420:
jsle r3, 2, jmp_04c8
jeq r3, 3, jmp_04f0
jne r3, 4, jmp_0548
ldxb r3, [r1+0]
jne r3, 255, jmp_06d0
stxdw [r2+8], r1
ldxdw r3, [r1+80]
add64 r1, r3
add64 r1, 10343
and64 r1, -8
ldxb r3, [r1+0]
jne r3, 255, jmp_0718
jmp_0480:
stxdw [r2+16], r1
ldxdw r3, [r1+80]
add64 r1, r3
add64 r1, 10343
and64 r1, -8
ldxb r3, [r1+0]
jne r3, 255, jmp_0760
jmp_04b8:
stxdw [r2+24], r1
ja jmp_0078
jmp_04c8:
jeq r3, 1, jmp_00a8
ldxb r3, [r1+0]
jne r3, 255, jmp_08a8
stxdw [r2+8], r1
ja jmp_0078
jmp_04f0:
ldxb r3, [r1+0]
jne r3, 255, jmp_0650
stxdw [r2+8], r1
ldxdw r3, [r1+80]
add64 r1, r3
add64 r1, 10343
and64 r1, -8
ldxb r3, [r1+0]
jne r3, 255, jmp_0698
jmp_0538:
stxdw [r2+16], r1
ja jmp_0078
jmp_0548:
ldxb r3, [r1+0]
jne r3, 255, jmp_0798
stxdw [r2+8], r1
ldxdw r3, [r1+80]
add64 r1, r3
add64 r1, 10343
and64 r1, -8
ldxb r3, [r1+0]
jne r3, 255, jmp_07e0
jmp_0590:
stxdw [r2+16], r1
ldxdw r3, [r1+80]
add64 r1, r3
add64 r1, 10343
and64 r1, -8
ldxb r3, [r1+0]
jne r3, 255, jmp_0828
jmp_05c8:
stxdw [r2+24], r1
ldxdw r3, [r1+80]
add64 r1, r3
add64 r1, 10343
and64 r1, -8
ldxb r3, [r1+0]
jne r3, 255, jmp_0870
jmp_0600:
stxdw [r2+32], r1
ja jmp_0078
jmp_0610:
lsh64 r2, 3
mov64 r3, r10
add64 r3, 16
add64 r3, r2
ldxdw r2, [r3+0]
stxdw [r10+24], r2
jmp_0640:
add64 r1, 8
ja jmp_00a8
jmp_0650:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+8], r3
add64 r1, 8
ldxb r3, [r1+0]
jeq r3, 255, jmp_0538
jmp_0698:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+16], r3
ja jmp_0640
jmp_06d0:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+8], r3
add64 r1, 8
ldxb r3, [r1+0]
jeq r3, 255, jmp_0480
jmp_0718:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+16], r3
add64 r1, 8
ldxb r3, [r1+0]
jeq r3, 255, jmp_04b8
jmp_0760:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+24], r3
ja jmp_0640
jmp_0798:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+8], r3
add64 r1, 8
ldxb r3, [r1+0]
jeq r3, 255, jmp_0590
jmp_07e0:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+16], r3
add64 r1, 8
ldxb r3, [r1+0]
jeq r3, 255, jmp_05c8
jmp_0828:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+24], r3
add64 r1, 8
ldxb r3, [r1+0]
jeq r3, 255, jmp_0600
jmp_0870:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+32], r3
ja jmp_0640
jmp_08a8:
lsh64 r3, 3
mov64 r4, r10
add64 r4, 16
add64 r4, r3
ldxdw r3, [r4+0]
stxdw [r2+8], r3
ja jmp_0640
jmp_08e0:
mov32 r3, 7256
hor64 r3, 0
mov64 r1, 0
mov64 r2, 0
call fn_09a8
ldxdw r2, [r1+8]
ldxdw r1, [r2+0]
ldxdw r2, [r2+8]
add64 r2, -1
call sol_log_
mov32 r1, 6985
hor64 r1, 0
mov64 r2, 14
call sol_log_
exit
fn_0958:
call fn_0960
fn_0960:
call custom_panic
call abort
fn_0970:
add64 r10, -64
stxdw [r10+48], r2
stxdw [r10+40], r1
sth [r10+56], 1
mov64 r1, r10
add64 r1, 40
call fn_0958
fn_09a8:
add64 r10, -128
stxdw [r10+40], r2
stxdw [r10+32], r1
mov32 r1, 7280
hor64 r1, 0
stxdw [r10+48], r1
mov64 r1, r10
add64 r1, 96
stxdw [r10+64], r1
mov64 r1, r10
add64 r1, 32
stxdw [r10+112], r1
mov32 r1, 6208
hor64 r1, 0
stxdw [r10+120], r1
stxdw [r10+104], r1
mov64 r1, r10
add64 r1, 40
stxdw [r10+96], r1
stdw [r10+80], 0
stdw [r10+56], 2
stdw [r10+72], 2
mov64 r1, r10
add64 r1, 48
mov64 r2, r3
call fn_0970
fn_0a78:
add64 r10, -128
mov64 r0, r1
ldxdw r9, [r10+120]
stxdw [r10+80], r9
jeq r2, 0, jmp_0ad8
mov32 r2, 1114112
ldxw r6, [r0+16]
mov64 r1, r6
and32 r1, 2097152
jeq r1, 0, jmp_0af0
mov32 r2, 43
ja jmp_0ae8
jmp_0ad8:
mov32 r2, 45
ldxw r6, [r0+16]
jmp_0ae8:
add64 r9, 1
jmp_0af0:
mov64 r1, r6
and32 r1, 8388608
stxdw [r10+96], r4
stxw [r10+88], r2
jne r1, 0, jmp_0bd0
mov64 r1, 0
stxdw [r10+104], r1
mov64 r7, r9
ldxh r2, [r0+20]
jlt r7, r2, jmp_0cd0
jmp_0b40:
mov64 r9, r5
ldxdw r8, [r0+8]
ldxdw r7, [r0+0]
mov64 r1, r7
mov64 r2, r8
ldxw r3, [r10+88]
ldxdw r4, [r10+104]
ldxdw r5, [r10+96]
call fn_10a0
mov32 r3, 1
jne r0, 0, jmp_1088
ldxdw r4, [r8+24]
mov64 r1, r7
mov64 r2, r9
ldxdw r3, [r10+80]
callx r4
mov64 r3, r0
ja jmp_1088
jmp_0bd0:
stxdw [r10+104], r3
jge r4, 32, jmp_0c68
mov64 r7, 0
jeq r4, 0, jmp_0cb8
ldxdw r1, [r10+104]
mov64 r2, r4
ja jmp_0c28
jmp_0c08:
add64 r7, r3
add64 r1, 1
add64 r2, -1
jeq r2, 0, jmp_0cb8
jmp_0c28:
ldxb r4, [r1+0]
lsh32 r4, 24
arsh32 r4, 24
mov32 r3, 1
mov32 r4, r4
jsgt r4, -65, jmp_0c08
mov32 r3, 0
ja jmp_0c08
jmp_0c68:
mov64 r1, r3
mov64 r2, r4
mov64 r7, r6
mov64 r6, r5
mov64 r8, r0
call fn_1148
mov64 r5, r6
mov64 r6, r7
mov64 r7, r0
mov64 r0, r8
jmp_0cb8:
add64 r7, r9
ldxh r2, [r0+20]
jge r7, r2, jmp_0b40
jmp_0cd0:
and32 r2, -1
mov64 r1, r6
and32 r1, 16777216
stxdw [r10+64], r5
jne r1, 0, jmp_0d48
and32 r7, -1
sub32 r2, r7
mov64 r1, r6
rsh32 r1, 29
and32 r1, 3
jsgt r1, 1, jmp_0e60
mov32 r8, 0
jeq r1, 0, jmp_0e88
mov64 r8, r2
ja jmp_0e88
jmp_0d48:
stxdw [r10+72], r2
ldxdw r1, [r0+16]
stxdw [r10+56], r1
and32 r1, -1
and32 r1, -1612709888
or32 r1, 536870960
stxw [r0+16], r1
ldxdw r8, [r0+0]
stxdw [r10+112], r0
ldxdw r9, [r0+8]
mov64 r1, r8
mov64 r2, r9
ldxw r3, [r10+88]
ldxdw r4, [r10+104]
ldxdw r5, [r10+96]
call fn_10a0
mov32 r3, 1
jne r0, 0, jmp_1088
and32 r7, -1
ldxdw r2, [r10+72]
sub32 r2, r7
mov32 r7, 0
and32 r2, 65535
jmp_0e00:
mov64 r1, r7
and32 r1, 65535
jge r1, r2, jmp_1030
ldxdw r3, [r9+32]
mov64 r1, r8
mov64 r6, r2
mov32 r2, 48
callx r3
mov64 r2, r6
add32 r7, 1
jeq r0, 0, jmp_0e00
ja jmp_0f10
jmp_0e60:
mov64 r8, r2
jne r1, 2, jmp_0e88
mov64 r8, r2
and32 r8, 65534
rsh32 r8, 1
jmp_0e88:
stxdw [r10+72], r2
and32 r6, 2097151
stxw [r10+112], r6
mov32 r6, 0
ldxdw r7, [r0+8]
ldxdw r9, [r0+0]
jmp_0eb8:
mov64 r1, r8
and32 r1, 65535
mov64 r2, r6
and32 r2, 65535
jge r2, r1, jmp_0f20
ldxdw r3, [r7+32]
mov64 r1, r9
ldxw r2, [r10+112]
callx r3
add32 r6, 1
jeq r0, 0, jmp_0eb8
jmp_0f10:
mov32 r3, 1
ja jmp_1088
jmp_0f20:
mov64 r1, r9
mov64 r2, r7
ldxw r3, [r10+88]
ldxdw r4, [r10+104]
ldxdw r5, [r10+96]
call fn_10a0
mov32 r3, 1
jne r0, 0, jmp_1088
ldxdw r4, [r7+24]
mov64 r1, r9
ldxdw r2, [r10+64]
ldxdw r3, [r10+80]
callx r4
mov32 r3, 1
ldxdw r6, [r10+72]
jne r0, 0, jmp_1088
sub32 r6, r8
mov32 r8, 0
and32 r6, 65535
jmp_0fb8:
mov64 r1, r8
and32 r1, 65535
mov32 r3, 1
jlt r1, r6, jmp_0fe0
mov32 r3, 0
jmp_0fe0:
jge r1, r6, jmp_1088
stxw [r10+104], r3
ldxdw r3, [r7+32]
mov64 r1, r9
ldxw r2, [r10+112]
callx r3
ldxw r3, [r10+104]
add32 r8, 1
jeq r0, 0, jmp_0fb8
ja jmp_1088
jmp_1030:
ldxdw r4, [r9+24]
mov64 r1, r8
ldxdw r2, [r10+64]
ldxdw r3, [r10+80]
callx r4
mov32 r3, 1
jne r0, 0, jmp_1088
ldxdw r1, [r10+112]
ldxdw r2, [r10+56]
stxdw [r1+16], r2
mov32 r3, 0
jmp_1088:
and32 r3, 1
mov64 r0, r3
exit
fn_10a0:
mov64 r6, r5
mov64 r7, r4
mov64 r8, r2
mov32 r2, r3
jeq r2, 1114112, jmp_1108
ldxdw r4, [r8+32]
mov64 r9, r1
mov64 r2, r3
callx r4
mov64 r1, r9
mov64 r2, r0
mov32 r0, 1
jne r2, 0, jmp_1140
jmp_1108:
jeq r7, 0, jmp_1138
ldxdw r4, [r8+24]
mov64 r2, r7
mov64 r3, r6
callx r4
ja jmp_1140
jmp_1138:
mov32 r0, 0
jmp_1140:
exit
fn_1148:
add64 r10, -64
mov64 r7, r1
add64 r7, 7
and64 r7, -8
mov64 r3, r7
sub64 r3, r1
jge r2, r3, jmp_11f8
jmp_1180:
mov64 r0, 0
jne r2, 0, jmp_11b8
ja jmp_1718
jmp_1198:
add64 r0, r3
add64 r1, 1
add64 r2, -1
jeq r2, 0, jmp_1718
jmp_11b8:
ldxb r4, [r1+0]
lsh32 r4, 24
arsh32 r4, 24
mov32 r3, 1
mov32 r4, r4
jsgt r4, -65, jmp_1198
mov32 r3, 0
ja jmp_1198
jmp_11f8:
mov64 r5, r2
sub64 r5, r3
jlt r5, 8, jmp_1180
stxdw [r10+56], r3
mov64 r2, r5
and64 r2, 7
mov64 r0, 0
mov64 r3, 0
jne r7, r1, jmp_1550
jmp_1240:
ldxdw r4, [r10+56]
add64 r1, r4
jeq r2, 0, jmp_12e8
mov64 r0, r5
and64 r0, -8
mov64 r4, r1
add64 r4, r0
mov64 r0, 0
ja jmp_12a8
jmp_1288:
add64 r0, r6
add64 r4, 1
add64 r2, -1
jeq r2, 0, jmp_12e8
jmp_12a8:
ldxb r7, [r4+0]
lsh32 r7, 24
arsh32 r7, 24
mov32 r6, 1
mov32 r7, r7
jsgt r7, -65, jmp_1288
mov32 r6, 0
ja jmp_1288
jmp_12e8:
rsh64 r5, 3
add64 r0, r3
ja jmp_13a8
jmp_1300:
mov64 r1, r2
add64 r1, r5
ldxdw r9, [r10+56]
mov64 r7, r9
and64 r7, 3
mov64 r5, r3
sub64 r5, r9
mov32 r6, 16711935
hor64 r6, 16711935
mov64 r8, r4
and64 r8, r6
rsh64 r4, 8
and64 r4, r6
add64 r4, r8
mov32 r6, 65537
hor64 r6, 65537
lmul64 r4, r6
rsh64 r4, 48
add64 r4, r0
mov64 r0, r4
jne r7, 0, jmp_1608
jmp_13a8:
mov64 r3, r5
mov64 r2, r1
jeq r3, 0, jmp_1718
mov64 r5, r3
jlt r3, 192, jmp_13d8
mov64 r5, 192
jmp_13d8:
stxdw [r10+56], r5
lsh64 r5, 3
mov64 r4, 0
jlt r3, 4, jmp_1300
mov64 r4, r5
and64 r4, 2016
mov64 r1, r2
add64 r1, r4
mov64 r4, 0
mov64 r7, r2
jmp_1428:
ldxdw r9, [r7+0]
mov64 r8, r9
rsh64 r8, 6
xor64 r9, -1
rsh64 r9, 7
or64 r9, r8
mov32 r8, 16843009
hor64 r8, 16843009
and64 r9, r8
add64 r9, r4
ldxdw r4, [r7+8]
mov64 r6, r4
rsh64 r6, 6
xor64 r4, -1
rsh64 r4, 7
or64 r4, r6
and64 r4, r8
add64 r4, r9
ldxdw r9, [r7+16]
mov64 r6, r9
rsh64 r6, 6
xor64 r9, -1
rsh64 r9, 7
or64 r9, r6
and64 r9, r8
add64 r9, r4
ldxdw r4, [r7+24]
mov64 r6, r4
rsh64 r6, 6
xor64 r4, -1
rsh64 r4, 7
or64 r4, r6
and64 r4, r8
add64 r4, r9
add64 r7, 32
jne r7, r1, jmp_1428
ja jmp_1300
jmp_1550:
mov64 r6, r1
sub64 r6, r7
mov64 r7, r1
ja jmp_1590
jmp_1570:
add64 r3, r9
add64 r7, 1
mov32 r4, r8
jeq r4, 1, jmp_1240
jmp_1590:
ldxb r9, [r7+0]
lsh32 r9, 24
arsh32 r9, 24
mov32 r8, 1
mov32 r4, r9
mov32 r9, 1
jsle r4, -65, jmp_15e0
add64 r6, 1
jeq r6, 0, jmp_1570
ja jmp_15f8
jmp_15e0:
mov32 r9, 0
add64 r6, 1
jeq r6, 0, jmp_1570
jmp_15f8:
mov32 r8, 0
ja jmp_1570
jmp_1608:
and64 r9, 252
lsh64 r9, 3
jlt r3, 192, jmp_1628
mov64 r3, 192
jmp_1628:
add64 r2, r9
mov64 r1, 0
and64 r3, 3
lsh64 r3, 3
jmp_1648:
ldxdw r0, [r2+0]
mov64 r5, r0
rsh64 r5, 6
xor64 r0, -1
rsh64 r0, 7
or64 r0, r5
mov32 r5, 16843009
hor64 r5, 16843009
and64 r0, r5
add64 r0, r1
add64 r2, 8
add64 r3, -8
mov64 r1, r0
jne r3, 0, jmp_1648
mov32 r1, 16711935
hor64 r1, 16711935
mov64 r2, r0
and64 r2, r1
rsh64 r0, 8
and64 r0, r1
add64 r0, r2
mov32 r1, 65537
hor64 r1, 65537
lmul64 r0, r1
rsh64 r0, 48
add64 r0, r4
jmp_1718:
exit
add64 r10, -64
mov64 r3, 20
ldxdw r1, [r1+0]
mov64 r4, r1
jlt r1, 1000, jmp_1878
mov64 r3, 16
mov64 r4, r1
jmp_1758:
mov64 r5, r4
mov64 r0, r5
and32 r0, -1
udiv64 r4, 10000
mov64 r6, r4
and32 r6, -1
lmul32 r6, 10000
sub32 r0, r6
mov64 r6, r0
and32 r6, 65535
udiv32 r6, 100
mov64 r7, r6
lmul32 r7, 100
sub32 r0, r7
mov32 r7, 7050
hor64 r7, 0
lsh32 r0, 1
and64 r0, 65534
lsh32 r6, 1
mov64 r8, r7
add64 r8, r0
add64 r7, r6
mov64 r0, r10
add64 r0, 44
add64 r0, r3
ldxb r6, [r7+1]
stxb [r0+1], r6
ldxb r6, [r7+0]
stxb [r0+0], r6
ldxb r6, [r8+1]
stxb [r0+3], r6
ldxb r6, [r8+0]
stxb [r0+2], r6
add64 r3, -4
jgt r5, 9999999, jmp_1758
add64 r3, 4
jmp_1878:
jle r4, 9, jmp_1940
and32 r4, -1
mov64 r5, r4
and32 r5, 65535
udiv32 r5, 100
mov64 r0, r5
lmul32 r0, 100
sub32 r4, r0
lsh32 r4, 1
mov32 r0, 7050
hor64 r0, 0
and64 r4, 65534
add64 r0, r4
mov64 r4, r10
add64 r4, 44
mov64 r6, r4
add64 r6, r3
ldxb r7, [r0+1]
stxb [r6-1], r7
add64 r3, -2
add64 r4, r3
ldxb r0, [r0+0]
stxb [r4+0], r0
jne r1, 0, jmp_1950
ja jmp_1958
jmp_1940:
mov64 r5, r4
jeq r1, 0, jmp_1958
jmp_1950:
jeq r5, 0, jmp_19b0
jmp_1958:
mov32 r1, 7050
hor64 r1, 0
lsh64 r5, 1
and64 r5, 30
add64 r1, r5
add64 r3, -1
mov64 r4, r10
add64 r4, 44
add64 r4, r3
ldxb r1, [r1+1]
stxb [r4+0], r1
jmp_19b0:
mov64 r1, r3
sub64 r1, 20
stxdw [r10-8], r1
mov64 r5, r10
add64 r5, 44
add64 r5, r3
mov64 r1, r2
mov32 r2, 1
mov64 r3, 1
mov64 r4, 0
call fn_0a78
exit
.rodata
data_0000: .byte 0x66, 0x69, 0x62, 0x6f, 0x6e, 0x61, 0x63, 0x63, 0x69, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x2e, 0x72, 0x73, 0x00, 0x2a, 0x2a, 0x20, 0x50, 0x41, 0x4e, 0x49, 0x43, 0x4b, 0x45, 0x44, 0x20, 0x2a, 0x2a, 0x00, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x20, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x69, 0x73, 0x20, 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, 0x31, 0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39, 0x32, 0x30, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, 0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, 0x32, 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, 0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, 0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39, 0x34, 0x30, 0x34, 0x31, 0x34, 0x32, 0x34, 0x33, 0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37, 0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x35, 0x31, 0x35, 0x32, 0x35, 0x33, 0x35, 0x34, 0x35, 0x35, 0x35, 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39, 0x36, 0x30, 0x36, 0x31, 0x36, 0x32, 0x36, 0x33, 0x36, 0x34, 0x36, 0x35, 0x36, 0x36, 0x36, 0x37, 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31, 0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, 0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39, 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33, 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, 0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31, 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39The Rust implementation introduces some compute unit overhead compared to assembly:
test_rs
rs
#[test]
fn test_rs() {
test_fibonacci_program(ProgramLanguage::Rust, false);
}Test results
sh
Fibonacci numbers and compute units:
F(0): 0 (Compute Units: 13)
F(1): 1 (Compute Units: 14)
F(2): 1 (Compute Units: 23)
F(3): 2 (Compute Units: 28)
F(4): 3 (Compute Units: 33)
F(5): 5 (Compute Units: 38)
F(6): 8 (Compute Units: 43)
F(7): 13 (Compute Units: 48)
F(8): 21 (Compute Units: 53)
F(9): 34 (Compute Units: 58)
F(10): 55 (Compute Units: 63)
F(11): 89 (Compute Units: 68)
F(12): 144 (Compute Units: 73)
F(13): 233 (Compute Units: 78)
F(14): 377 (Compute Units: 83)
F(15): 610 (Compute Units: 88)
F(16): 987 (Compute Units: 93)
F(17): 1597 (Compute Units: 98)
F(18): 2584 (Compute Units: 103)
F(19): 4181 (Compute Units: 108)
F(20): 6765 (Compute Units: 113)
F(21): 10946 (Compute Units: 118)
F(22): 17711 (Compute Units: 123)
F(23): 28657 (Compute Units: 128)
F(24): 46368 (Compute Units: 133)
F(25): 75025 (Compute Units: 138)
F(26): 121393 (Compute Units: 143)
F(27): 196418 (Compute Units: 148)
F(28): 317811 (Compute Units: 153)
F(29): 514229 (Compute Units: 158)
F(30): 832040 (Compute Units: 163)
F(31): 1346269 (Compute Units: 168)
F(32): 2178309 (Compute Units: 173)
F(33): 3524578 (Compute Units: 178)
F(34): 5702887 (Compute Units: 183)
F(35): 9227465 (Compute Units: 188)
F(36): 14930352 (Compute Units: 193)
F(37): 24157817 (Compute Units: 198)
F(38): 39088169 (Compute Units: 203)
F(39): 63245986 (Compute Units: 208)
F(40): 102334155 (Compute Units: 213)
F(41): 165580141 (Compute Units: 218)
F(42): 267914296 (Compute Units: 223)
F(43): 433494437 (Compute Units: 228)
F(44): 701408733 (Compute Units: 233)
F(45): 1134903170 (Compute Units: 238)
F(46): 1836311903 (Compute Units: 243)
F(47): 2971215073 (Compute Units: 248)
test tests::test_rs ... ok
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 14 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xfffffffe
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 13 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... success
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 14 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 23 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 28 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x2
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 33 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x3
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 38 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x5
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 43 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x8
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 48 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xd
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 53 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x15
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 58 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x22
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 63 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x37
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 68 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x59
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 73 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x90
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 78 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xe9
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 83 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x179
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 88 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x262
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 93 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x3db
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 98 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x63d
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 103 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xa18
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 108 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1055
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 113 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1a6d
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 118 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x2ac2
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 123 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x452f
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 128 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x6ff1
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 133 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xb520
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 138 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x12511
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 143 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1da31
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 148 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x2ff42
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 153 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x4d973
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 158 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x7d8b5
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 163 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xcb228
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 168 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x148add
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 173 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x213d05
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 178 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x35c7e2
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 183 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x5704e7
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 188 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x8cccc9
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 193 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xe3d1b0
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 198 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x1709e79
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 203 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x2547029
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 208 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x3c50ea2
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 213 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x6197ecb
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 218 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x9de8d6d
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 223 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xff80c38
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 228 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x19d699a5
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 233 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x29cea5dd
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 238 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x43a53f82
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 243 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0x6d73e55f
[ ... DEBUG ... ] Program DASMAC... invoke [1]
[ ... DEBUG ... ] Program DASMAC... consumed 248 of 1400000 compute units
[ ... DEBUG ... ] Program DASMAC... failed: custom program error: 0xb11924e1✅ All tests
tests.rs
rs
use std::vec;
use fib_rs::Fib;
use mollusk_svm::result::Check;
use solana_sdk::instruction::Instruction;
use solana_sdk::program_error::ProgramError;
use test_utils::{setup_test, single_mock_account, ProgramLanguage};
const MAX_FIB_INDEX_U32: u8 = 47;
const E_PASSED_ACCOUNT: u32 = u32::MAX;
const E_INDEX_TOO_BIG: u32 = u32::MAX - 1;
fn fib(n: u8) -> u64 {
Fib::single(n.into()).try_into().unwrap()
}
fn test_fibonacci_program(language: ProgramLanguage, test_account_error: bool) {
let setup = setup_test(language);
if test_account_error {
// Verify failure for passing an account.
let (account, accounts) = single_mock_account();
setup.mollusk.process_and_validate_instruction(
&Instruction::new_with_bytes(setup.program_id, &[], accounts.clone()),
&[account],
&[Check::err(ProgramError::Custom(E_PASSED_ACCOUNT))],
);
}
// Verify failure for index too big.
setup.mollusk.process_and_validate_instruction(
&Instruction::new_with_bytes(setup.program_id, &[MAX_FIB_INDEX_U32 + 1], vec![]),
&[],
&[Check::err(ProgramError::Custom(E_INDEX_TOO_BIG))],
);
// Initialize a vector with 48 slots, one for each Fibonacci number from F(0) to F(47), along
// with their compute unit consumption.
let mut fib_numbers: Vec<(u32, u64)> = vec![(0, 0); (MAX_FIB_INDEX_U32 + 1) as usize];
// For F(0) = 0, the program result should be considered a success.
fib_numbers[0] = (
0,
setup
.mollusk
.process_and_validate_instruction(
&Instruction::new_with_bytes(setup.program_id, &[0], vec![]),
&[],
&[Check::success()],
)
.compute_units_consumed,
);
// For F(1) onwards, verify correct Fibonacci numbers are returned as a custom error.
for n in 1..=MAX_FIB_INDEX_U32 {
let expected_fib: u32 = fib(n) as u32;
fib_numbers[n as usize] = (
expected_fib,
setup
.mollusk
.process_and_validate_instruction(
&Instruction::new_with_bytes(setup.program_id, &[n], vec![]),
&[],
&[Check::err(ProgramError::Custom(expected_fib))],
)
.compute_units_consumed,
);
}
// Pretty print the Fibonacci numbers along with their compute unit consumption.
println!("Fibonacci numbers and compute units:");
for n in 0..=MAX_FIB_INDEX_U32 {
println!(
"{:<7}{:<10} (Compute Units: {})",
format!("F({}):", n),
fib_numbers[n as usize].0,
fib_numbers[n as usize].1
);
}
}
#[test]
fn test_asm() {
test_fibonacci_program(ProgramLanguage::Assembly, true);
}
#[test]
fn test_rs() {
test_fibonacci_program(ProgramLanguage::Rust, false);
}
/// Verify the index of the maximum Fibonacci number that fits in a u32, while allowing space for
/// two error codes that may be returned by the Fibonacci program.
#[test]
fn test_max_fib_u32() {
assert!(fib(MAX_FIB_INDEX_U32) <= E_INDEX_TOO_BIG.into());
assert!(fib(MAX_FIB_INDEX_U32 + 1) > u32::MAX.into());
}NOTE
The assembly file in this example was adapted from an implementation by 7etsuo.