لهجةُ التجميعِ العربيّة
حين لا تكفيك مدمَجةٌ، تنزلُ إلى التجميع. وفي ص طريقانِ لا واحد، وفرقُهما جوهريٌّ لا ذوقيّ:
تجميع … نهاية | @تجميع("...") | |
|---|---|---|
| القاعدة | gr.adv.asm_dialect | gr.adv.inline_asm |
| النصّ | منمنماتٌ عربيّةٌ مفحوصة | سلسلةُ مُجمِّعٍ خام |
| الفحص | معجمُ معماريّةِ الهدف | لا فحص |
| المراسي | ٢٩ بذرةً | ٢ |
$ find tests/behavior/rules_matrix/60_advanced/gr.adv.asm_dialect -name '*.ص' | wc -l
29
$ find tests/behavior/rules_matrix/60_advanced/gr.adv.inline_asm -name '*.ص' | wc -l
2@تجميع الخامُّ حدٌّ مُعلَن
مرساتانِ اثنتانِ لا غير، وهو مُعلَنٌ حدًّا في حدودِ المسار. فإن كان لِما تريدُه منمنمةٌ في المعجم، فالكتلةُ المفحوصةُ أوثقُ بمرتبة.
١ · الكتلةُ المفحوصة
دالة أوقف_المعالج() لا_ترجع
تجميع
عطّل_المقاطعات
حلقة: أوقف
اقفز حلقة
نهاية
نهايةcall void asm sideeffect alignstack "cli\0A\09hlt", ""()عناصرُ الكتلة، كما يُعلِنُها language-truth/dialects/assembly.yaml:
| العنصر | الصيغة |
|---|---|
| الفاتحةُ والخاتمة | تجميع … نهاية (وبينهما متطاير اختياريّة) |
| فاصلُ المعاملات | الفاصلةُ العربيّةُ ، |
| التعليق | # |
| اللصيقة | اسم: |
| السجلّ | اسمٌ عربيٌّ من جدولِ سجلّاتِ المعماريّة |
| الثابت | عددٌ (بأرقامٍ عربيّةٍ أو هنديّة) |
| العنونة | [القاعدة + العدّاد × ٤ + ٨] |
| متغيّرُ ص | {اسم} ⇒ ربطٌ تلقائيٌّ بقيدِ InlineAsm |
| التلويث | يلوّث(الذاكرة، الأعلام) ⇒ ~{memory} · ~{cc} |
٢ · متغيّرُ ص داخلَ الكتلة
متغير أ = 5
متغير ب = 3
متغير ناتج = 0
تجميع
انقل {ناتج}، {أ}
اجمع {ناتج}، {ب}
نهاية
اطبع_سطر(ناتج)يُترجَمُ على x86_64 برمزِ خروجٍ صفر. الترتيبُ الوجهةُ أوّلًا ثمّ المصدر على المعماريّاتِ الأربعِ جميعًا — والفرقُ في النكهةِ المُصدَرةِ وحدَها.
لكنّ الرتبةَ ليست محمولة
اضرب معاملانِ على aarch64 وriscv64 (الوجهةُ تُكرَّرُ مصدرًا أوّل في العتاد)، ومعاملٌ واحد على x86_64 وi686 (mul بكتاباتٍ ضمنيّةٍ في المركم والبيانات). فالمرسى basic/005_aarch64_three_operand.ص يحملُ @arch: aarch64 riscv64 صراحةً، والصيغةُ ذاتُها على x86 تُرفَض — مقيسًا:
⛔ [SEM026] المنمنمة «اضرب» تتطلّب 1 معاملًا، ووُجد 2.فراجِعْ حقلَ operands في معجمِ هدفِك قبلَ أن تفترضَ الحمل.
٣ · أربعُ معماريّاتٍ بأربعةِ معاجم
قِيسَت من language-truth/dialects/assembly_mnemonics/:
| المعجم | منمنمة | سجلًّا | بادئةُ السجلّ | بادئةُ الثابت | الترتيب | العنونة |
|---|---|---|---|---|---|---|
x86_64 | ٦٨ | ٣٤ | % | $ | المصدرُ أوّلًا | إزاحة(قاعدة) |
i686 | ٧٠ | ٢٢ | % | $ | المصدرُ أوّلًا | إزاحة(قاعدة) |
aarch64 | ٧٦ | ٦٦ | — | # | الوجهةُ أوّلًا | [قاعدة، إزاحة] |
riscv64 | ٤٢ | ٤٦ | — | — | الوجهةُ أوّلًا | إزاحة(قاعدة) |
| المجموع | ٢٥٦ |
لماذا riscv64 هي البرهان
نكهتُها تركيبةٌ لم تظهر في الثلاثةِ السابقة: الوجهةُ أوّلًا وصريحةٌ كـAArch64، والعنونةُ 8(x1) كـAT&T، ولا بادئةَ لسجلٍّ ولا لثابتٍ أصلًا. فلو كان المحورانِ مقترنَينِ في الخافض (وجهةٌ-أوّلًا ⇒ أقواسٌ مربّعة) لظهرَ العطبُ هنا حتمًا. والاختبارُ الحاسم: المصدرُ نفسُه لهدفَين ⇒ نصّانِ مختلفان (test_asm_riscv64.py).
خمسُ فئاتٍ في كلِّ معجم: نقل_وبيانات · حساب · منطق_وبتّات · قفز_وتحكّم · مقاطعات_ونظام (وسادسةٌ سلاسل_وذاكرة في عائلةِ x86). وأمثلة: انقل · اجمع · وافق · ضمّ · خالف · اقفز_إذا_ساوى · عطّل_المقاطعات · أوقف · حمّل_عنوان.
الاسمُ يُحمَل، والتعليمةُ لا تُحمَل
أوقف تُخفَضُ hlt على x86 وwfi على RISC-V؛ وعطّل_المقاطعات هناك ليست cli بل csri mstatus, 8. فالاسمُ العربيُّ مشتركٌ حيث الدلالةُ مشتركة، لا حيث الترميزُ مشترك.
⚠️ وتشخيصُ SEM025 أعلاه يعدُّ ستًّا «محمولةً على المعماريّاتِ كلّها» ومنها قارن — ومعجمُ riscv64 نفسُه يقول: «لا «قارن» في RISC-V: المقارنةُ تُنتِجُ قيمةً أو تُدمَجُ في القفز» (المُعلَنُ هناك قارن_أصغر). فاعتمِدْ على المعجمِ لا على نصِّ الاقتراح.
٤ · التشخيصاتُ الخمسة
كلُّ ما يلي مخرَجٌ حقيقيّ.
SEM025 — منمنمةٌ خارجَ المعجم
⛔ [SEM025] المنمنمة «اجمع_رباعي» غير موجودة في معجم لهجة التجميع.
هل تقصد: اجمع_بالحمل، اعكس_البتات، خزن_مربعا؟
💡 استعمل منمنمة من معجم معماريّة الهدف (انقل/اجمع/قارن/اقفز/
عطّل_المقاطعات/أوقف محمولة على المعماريّات كلّها)، أو أضِفها بقرار لغويّ
في language-truth/dialects/assembly_mnemonics/<المعماريّة>.yaml
📍 الموقع: السطر 3، العمود 9والإضافةُ قرارُ لغةٍ في مصدرِ الحقيقة، لا رقعةٌ في C++.
SEM026 — عددُ معاملاتٍ مخالف
⛔ [SEM026] المنمنمة «اجمع» تتطلّب 2 معاملًا، ووُجد 3.
💡 طابِق عدد المعاملات لِما يعرّفه المعجم للمنمنمة
(مثال: «انقل وجهة، مصدر» معاملان؛ «أوقف» بلا معاملات).SEM033 — سجلٌّ خارجَ المعجم
⛔ [SEM033] السجلّ «صفر» غير موجود في معجم سجلّات لهجة التجميع.
هل تقصد: الصفر، سجل_٠، سجل_١؟الاقتراحاتُ من معجمِ الهدفِ نفسِه: صفر على i686 يقترحُ سجل_٨، سجل_٩، المركم، وعلى riscv64 يقترحُ الصفر، سجل_٠، سجل_١.
والباقيان
SEM034 لمتغيّرِ ص في موضعِ مصدرٍ تكتبُه المنمنمة (بادل)، وSEM044 لهدفٍ لا معجمَ لمعماريّتِه.
٥ · حدودٌ ومزالق
sadcوحدَها. التوجيهانِ مُعلَنانِcompiler_optional، وحالُهماexperimental.- رأسُ المعاملِ وذيلُه ليسا زينة. كتابةُ سجلِّ نظامٍ على AArch64 تكتبُ المُسجَّلَ أوّلًا (
msr vbar_el1, x0)، فلولاoperand_headما عبّرَ المعجمُ عن جدولِ متّجهاتٍ ولا مؤقّتٍ ولا عنوانِ عودةٍ من استثناء — وهي عصبُ شفرةِ النواة. - مُعدِّلُ الحجمِ كذلك.
حمّل_سجل_المهمة(ltr) معاملُهr/m16، فيُبَثُّ${N:w}لا$Nالمجرَّد — وإلّا خرجَltr %eaxفرفضَه المُجمِّع. وتحميلُTRأساسُ الانتقالِ إلى الحلقة ٣. - الأخطاءُ تتتالى. خطأٌ واحدٌ في الكتلةِ قد يُنتِجُ ثلاثةَ تشخيصات؛ ابدأْ بالأوّلِ دائمًا.
ما يلي
- MMIO والمنافذ — أكثرُ ما تريدُه له مدمَجةٌ سلفًا.
- معالجاتُ المقاطعات — الكعبُ مولَّدٌ، فلا تكتُبْه بيدك.
- الوضعُ الحرّ — لماذا لا مكتبةَ تحتَ هذا كلِّه.