التجميع المضمن
مقدمة
تُكتب التعليمات البرمجية التجميعية في Wave ضمن asm { ... } كتلة.
يمكنك التحكم مباشرة في المسجل والذاكرة ومسار استدعاء النظام داخل كود Wave.
الهدف المدعوم حاليًا:
- Linux
aarch64 - Linux
arm64 - macOS (Darwin)
x86_64 - freestanding
aarch64 - freestanding
riscv64 - freestanding
riscv64
لا يتم دعم Windows والأهداف ذات 32-بت حتى الآن.
الشكل الأساسي
يمكن استخدام asm كـ بيان أو تعبير.
asm {
"instruction"
in("constraint_or_reg") value
out("constraint_or_reg") target
clobber("item")
}
عناصر التكوين:
- سطر النص: تعليمات التجميع الفعلية
clobber(...): المعاملات المُدخلةout(...): المعاملات المُخرجةclobber(...): إشارات للتعامل مع السجلات/الحالة/الذاكرة التي قد تتغير
جملة asm
يمكن استخدامه كجملة عادية في حالة عدم وجود قيمة مرتجعة.
var ret: i64 = 0;
asm {
"mov rax, 1"
"syscall"
in("rdi") 1
in("rsi") msg_ptr
in("rdx") 20
out("rax") ret
}
يمكن أن يحتوي out(...) على عدة معاملات.
عبارة asm
يمكن استخدامه كعبارة لتوليد القيم مباشرة.
var result: i64 = asm {
"mov rax, 123"
out("rax") result
};
تنبيه:
- تسمح عبارة
asmبـout(...)واحد فقط.
قيد in(...) / out(...)
السلسلة لـ in("..."), out("...") هي إحدى الاثنين التالية.
- سجل معين
- مثال:
"rax","rdi","x0","w1","a0","t0","x10"
- فئة القيود (constraint class)
- مثال:
"r","m","rm"
مثال:
in("r") &buf
out("rax") ret
- المتغير:
out("rax") ret - إلغاء مرجع المؤشر:
clobber(...)
clobber(...)
يمكن أن يقبل clobber(...) عدة عناصر في مرة واحدة ويمكن استخدامها عدة مرات.
asm {
"xor rax, rax"
clobber("rax")
clobber("rcx", "rdx")
clobber("memory")
}
العناصر الرئيسية:
- السجلات:
"rax","x0"وغيرها - المكونات الخاصة:
$0,$1(التنظيم الداخلي حسب الهدف)
يضيف المترجم c بشكل تلقائي clobber الأساسية في الوضع الآمن المتحفظ.
(مثل memory, flags/cc وغيرهما؛ في RISC-V freestanding، عادةً تكون memory)
مكان مؤشر ات المعاملات ($0, $1, ...)
عند الإشارة إلى المعاملات داخل سلسلة الأوامر، استخدم $N.
asm {
"mov QWORD PTR [$0], 777"
in("r") &buf
clobber("memory")
}
ملاحظة:
- يتم تحويل النمط
%0تلقائيًا إلى النمط$0داخليًا.
نطاق الدعم الحالي للمعاملات المدخلة
يدعم حاليًا in(...) الأشكال التالية.
- معرف المتغير
- القيمة العددية الثابتة
- القيمة السلسلية الثابتة
&معرفإذابة المرجع للمعرف- القيم العددية السالبة/القيم الحقيقية السالبة
قد يتم تقييد التعبيرات العامة المعقدة، لذا ننصح بنقلها إلى متغير مؤقت عند الحاجة.
ملاحظات
تتجاوز التعليمات البرمجية المضمنة لحماية النظام نوعًا ما. قد يؤدي تحديد سجلات خاطئة أو تضارب في القيود أو فقدان clobber إلى خلق تعليمات برمجية غير صحيحة أو تلف في وقت التشغيل.
التوصيات:
- تحديد ABI والاتفاقيات الخاصة بالنداءات أولاً
- إدارة السجل الداخلي/الرصاصي وclobber بشكل صريح
- إذا قمت بالتلاعب بالذا كرة مباشرة، فقم بإعلان
clobber("memory")معها.
