
Assembly Memo
在本單元中,我們將使用 sBPF Assembly 為程式建立一個日誌機制。
簡單的迷你備忘錄程式是您開始 sBPF Assembly 旅程的完美起點!
如果您不熟悉組合語言編程,請參考組合語言入門課程
Program Design
我們的程式將簡單地將正確的記憶體位置放入正確的暫存器,然後執行 sol_log_ 系統呼叫。它看起來像這樣:
sbpf
.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
程式首先宣告三個 .equ 常數,這些常數定義了指令數據的記憶體佈局:
sbpf
.equ NUM_ACCOUNTS, 0x00 ; Offset for number of accounts
.equ DATA_LEN, 0x08 ; Offset for data length
.equ DATA, 0x10 ; Offset for actual data這些常數標記了相對於 r1 的入口緩衝指針的位元組偏移量:
NUM_ACCOUNTS(0x0000):指向指令數據標頭中的帳戶數量,用於驗證DATA_LEN(0x08):指向指令數據標頭中的指令數據長度DATA(0x10):指向指令數據標頭中的指令數據
與抽象記憶體佈局的高級語言不同,組合語言需要精確知道每個數據的位置。
Entrypoint and Initial Validation
sbpf
.globl entrypoint
entrypoint:
ldxdw r0, [r1+NUM_ACCOUNTS] ; Load number of accounts into r0每個 sBPF 程式都從一個全域的 .entrypoint 符號開始。Solana 執行環境通過暫存器 r1 提供帳戶和指令數據。
第一條指令然後將帳戶數量載入到 r0 中。由於 r0 是虛擬機在退出時讀取的暫存器,這樣做有兩個目的:
載入帳戶數量供我們使用
如果傳遞了任何帳戶(r0 中的非零值),則確保程式會自動失敗
Sol Log Syscall
接下來,我們準備 sol_log_ 系統調用的參數:
sbpf
ldxdw r2, [r1+DATA_LEN] ; Load length of memo into r2
add64 r1, DATA ; Adjust r1 to point to memo bytes以下指令設置了 sol_log_ 的參數:
r2接收備忘錄數據的長度r1被調整為直接指向備忘錄字節
然後,我們調用 sol_log_ 並退出:
sbpf
call 16 ; Call sol_log_ (helper ID 16)
exit ; Return using r0 valueConclusion
該程序:
調用 16 (
sol_log_) 將備忘錄打印到驗證器日誌使用
r0中的值退出