
Assembly Memo
У цьому розділі ми використаємо sBPF Assembly для створення механізму логування для нашої програми.
Простота компактної програми для нотаток — ідеальна відправна точка для вашої подорожі у світ sBPF assembly!
Якщо ви не знайомі з програмуванням на асемблері, перегляньте вступний курс з Assembly
Program Design
Наша програма просто розмістить правильну адресу пам'яті у відповідний регістр, а потім виконає 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_
exitMemory Offsets
Програма починається з оголошення трьох констант .equ, які визначають розташування даних інструкцій у пам'яті:
.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
.globl entrypoint
entrypoint:
ldxdw r0, [r1+NUM_ACCOUNTS] ; Load number of accounts into r0Кожна програма sBPF починається з глобального символу .entrypoint. Середовище виконання Solana надає дані облікових записів та інструкцій через регістр r1.
Ця перша інструкція завантажує кількість облікових записів у r0. Оскільки r0 — це регістр, який VM зчитує при виході, це служить двом цілям:
Завантажує кількість облікових записів для нашого використання
Забезпечує автоматичний збій програми, якщо передаються будь-які облікові записи (ненульове значення в r0)
Системний виклик Sol Log
Далі ми підготуємо аргументи для системного виклику sol_log_:
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_ і виходимо:
call 16 ; Call sol_log_ (helper ID 16)
exit ; Return using r0 valueВисновок
Програма:
Викликає 16 (
sol_log_) для виведення нотатки в журнал валідатораВиходить, використовуючи значення в
r0