
Assembly Memo
In this unit we'll use sBPF Assembly to create a logging mechanism for our program.
The simplicity of a bite-size memo program is the perfect starting point for your sBPF assembly journey!
If you're unfamiliar with assembly programming, follow the introduction to Assembly course
Program Design
Our program will simply put the right memory location into the right register and then perform the sol_log_ syscall. It will look like this:
.equ NUM_ACCOUNTS, 0x00
.equ DATA_LEN, 0x08
.equ DATA, 0x10
.globl entrypoint
entrypoint:
ldxdw r0, [r1+NUM_ACCOUNTS]
ldxdw r2, [r1+DATA_LEN]
add64 r1, DATA
call sol_log_
exitMemory Offsets
The program begins by declaring three .equ constants that define the memory layout of our instruction data:
.equ NUM_ACCOUNTS, 0x00 ; Offset for number of accounts
.equ DATA_LEN, 0x08 ; Offset for data length
.equ DATA, 0x10 ; Offset for actual dataThese constants mark the byte-offsets relative to the entry-buffer pointer in r1:
NUM_ACCOUNTS(0x0000): Points to the account count in the instruction data header for validationDATA_LEN(0x08): Points to the instruction data length in the instruction data headerDATA(0x10): Points to the instruction data in the instruction data header
Unlike high-level languages that abstract memory layout, assembly requires knowing exactly where every piece of data lives.
Entrypoint and Initial Validation
.globl entrypoint
entrypoint:
ldxdw r0, [r1+NUM_ACCOUNTS] ; Load number of accounts into r0Every sBPF program starts at a global .entrypoint symbol. The Solana runtime provides account and instruction data through register r1.
This first instruction then loads the number of accounts into r0. Since r0 is the register the VM reads on exit, this serves two purposes:
- It loads the account count for our use
- It ensures the program will fail automatically if any accounts are passed (non-zero value in r0)
Sol Log Syscall
Next, we prepare the arguments for the sol_log_ syscall:
ldxdw r2, [r1+DATA_LEN] ; Load length of memo into r2
add64 r1, DATA ; Adjust r1 to point to memo bytesThese instructions set up the arguments for sol_log_:
r2receives the length of the memo datar1is adjusted to point directly to the memo bytes
And after that, we call sol_log_ and exit:
call 16 ; Call sol_log_ (helper ID 16)
exit ; Return using r0 valueConclusion
The program:
- Calls 16 (
sol_log_) to print the memo to the validator log - Exits using the value in
r0