
Assembly Memo
Trong bài học này, chúng ta sẽ sử dụng sBPF Assembly để tạo một cơ chế ghi log cho chương trình của chúng ta.
Sự đơn giản của một chường trình memo nhỏ là điểm khởi đầu lý tưởng cho hành trình của bạn trong việc học sBPF Assembly!
Nếu bạn không quen thuôc với ngôn ngữ lập trình assembly, bạn nên bắt đầu bằng cách đọc bài Giới thiệu về Assembly.
Thiết kế chương trình
Chương trình của chúng ta sẽ đơn giản là đặt địa chỉ bộ nhớ chính xác vào các register (thanh ghi) và sau đó gọi syscall sol_log_:
.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Độ lệch của bộ nhớ
Chương trình bắt đầu với việc khai báo 3 hằng số định nghĩa bố cục bộ nhớ của dữ liệu instruction của chúng ta bằng .equ:
.equ NUM_ACCOUNTS, 0x00 ; Offset for number of accounts
.equ DATA_LEN, 0x08 ; Offset for data length
.equ DATA, 0x10 ; Offset for actual dataNhững hằng số này đánh dấu các độ lệch byte tương ứng với con trỏ buffer vào trong thanh ghi r1:
NUM_ACCOUNTS(0x0000): trỏ đến số lượng tài khoản trong header của dữ liệu instruction để xác thực.DATA_LEN(0x08): trỏ đến độ dài dữ liệu instruction trong header của dữ liệu instruction.DATA(0x10): trỏ đến dữ liệu instruction trong header của dữ liệu instruction.
Không giống như những ngôn ngữ bậc cao khác trừu tượng hóa bố cục bộ nhớ, assembly yêu cầu bạn phải biết chính xác vị trí của từng dữ liệu.
Điểm đầu vào và Xác thực ban đầu
.globl entrypoint
entrypoint:
ldxdw r0, [r1+NUM_ACCOUNTS] ; Load number of accounts into r0Mỗi chương trình sBPF bắt đầu bởi một ký hiệu toàn cục .entrypoint. Runtime Solana cung cấp các tài khoản và dữ liệu instruction thông qua thanh ghi r1.
Instruction đầu tiên này sau đó tải số lượng accounts vào thành ghi r0. Vì r0 là thanh ghi mà máy ảo sẽ đọc khi thoát chương trình, điều này phục vụ hai mục đích:
Nó tải số lượng tài khoản vào cho chúng ta sử dụng
Nó đảm bảo rằng chương trình sẽ tự động thất bại nếu có bất kỳ tài khoản nào được chuyển vào (giá trị khác không trong r0)
Sol Log Syscall
Tiếp theo, chúng ta chuẩn bị các đối số cho syscall sol_log_:
ldxdw r2, [r1+DATA_LEN] ; Load length of memo into r2
add64 r1, DATA ; Adjust r1 to point to memo bytesNhững instruction này đặt các đối số cho syscall sol_log_:
r2nhận độ dài của dữ liệu memor1được điều chỉnh để trỏ trực tiếp đến các byte của dữ liệu memo
Và sau đó chúng ta gọi syscall sol_log_ và thoát chương trình:
call 16 ; Call sol_log_ (helper ID 16)
exit ; Return using r0 valueKết luận
Chương trình:
Gọi lệnh 16 (
sol_log_) để in một memo vào nhật ký validatorThoát chương trình sử dụng giá trị trong
r0