اسمبلر داخلی
معرفی
این سند به اسمبلر داخلی در زبان Wave میپردازد. اسمبلر داخلی یکی از قابلیتهای ارائهشده توسط Wave است که با حفظ سادگی زبانهای سطح بالا به دسترسی مستقیم به کنترل سختافزاری سطح پایین امکان میدهد.
به عبارتی، با استفاده از کد معمولی Wave، میتوان عملیات رجیستر پیچیده، دسترسی مستقیم به حافظه، اجرای دستورات خاص و غیره را ممکن ساخت، و در مواردی که بهینهسازی عملکرد یا عملیات وابسته به سختافزار ضروری است، از آن بهره میبرند.
دستور زبان پایه
اسم {
"دستورات اسمبلر" // کد واقعی اسمبلر (یک دستور در هر خط)
...
in("رجیستر") مقدار // نگاشت رجیستر ورودی
out("رجیستر") متغیر // نگاشت رجیستر خروجی
}
اجزای دستور زبان
-
دستورات اسمبلر
- به صورت رشته متنی
"..."
نوشته میشود و دستورات اسمبلر سطح پایین هستند که در CPU واقعی اجرا میشوند. - میتوان چندین خط نوشت، و در هر خط یک دستور نوشته میشود.
- مثال:
"mov rax, 1"
"syscall"
- به صورت رشته متنی
-
in("رجیستر") مقدار
- مقدار متغیر (یا عبارت) به رجیستر مشخصشده بارگذاری میشود.
- مثال:
-> مقدار متغیر
in("rdi") s
s
در رجیستر پارامتر اول syscall در استاندارد x86-64 که رجیسترrdi
است، گذاشته میشود.
-
out("رجیستر") متغیر
- مقدار رجیستر مشخصشده به متغیر Wave منتقل میشود.
- مثال:
-> مقدار رجیستر
out("rax") ret
rax
که نتیجه بازگشتیsyscall
در آن ذخیره شده است، در متغیرret
ذخیره میشود.
نمونه ساده
fun main() {
var msg_ptr: ptr<i8> = "سلام از syscall!\n";
var ret_val: i64;
asm {
"mov rax, 1"
"syscall"
in("rdi") 1
in("rsi") msg_ptr
in("rdx") 20
out("rax") ret_val
}
}
ملاحظات
- اسمبلر داخلی در Wave میتواند پایداری نوع را دور بزند، لذا استفاده نادرست از دستورات میتواند منجر به پایان غیرعادی برنامه یا وقوع رفتارهای پیشبینینشده شود.
- نگاشتهای
in
وout
در زمان کامپایل بررسی میشوند اما اعتبار خود دستورات تضمین نمیشود.