Assembly
Assembly Memo

Assembly Memo

18 Graduates

Assembly Memo

Assembly Memo Challenge

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_
  exit

Memory 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 是虛擬機在退出時讀取的暫存器,這樣做有兩個目的:

  1. 載入帳戶數量供我們使用

  2. 如果傳遞了任何帳戶(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 value

Conclusion

該程序:

  1. 調用 16 (sol_log_) 將備忘錄打印到驗證器日誌

  2. 使用 r0 中的值退出

準備好參加挑戰了嗎?
Blueshift © 2025Commit: e573eab