لغة التجميع

السؤال: ماهي لغة البرمجة المستعملة في معضم البرمجيات الطبية؟


راجع قسم "المصطلحات" أدناه، للحصول على معلومات خاصة باستعمال لفظة "تجميع" ولفظة "مجمع"

لغة التجميع  هي مجموعة من اللغات ذات المستوى المنخفض Low-Level (بمعنى أنها مصممة لتتعامل مع الحاسوب أكثر من كونها مصممة ليتم البرمجة بها) تستخدم في برمجة أجهزة الكمبيوتر، المعالجات الدقيقة Microprocessors، المتحكمات الدقيقة Microcontrollers، وفي برمجة الدوائر المتكاملة Integrated Circuits (IC).وتقوم تلك اللغات بتحويل الكود والثوابت اللازمة لبرمجة بناء معين من وحدات المعالجة المركزية CPU، من شكله المعتمد على الرموز Symbolic إلى شكل آخر رقمي يسمى "كود الآلة" Machine Code.هذا التحويل/التمثيل Representation يتم تعريفه عادة عبر الشركات المصنعة للأجهزة، ويعتمد على مجموعة من الاختصارات التي تساعد المبرمجين على تذكر تعليمات البرمجة والسجلات Registers المستخدمة في عمليات البرمجة بسهولة. وهناك لغة تجميع محددة لكل بناء حاسوبي سواء كان فعليا Physical أو افتراضيا Virtual (بعكس معظم لغات البرمجة عالية المستوى High-Level، التي عادة ما تعمل مع معظم أنظمة الحاسوب).
وتستخدم أداة برمجية تسمى "المجمِع" Assembler في ترجمة السطور والتعليمات Instructions المكودة عبر لغة التجميع إلى "كود الآلة" التي يتم التعامل معها.ويقوم المجمع بتنفيذ ترجمة تماثلية (مثال: سطر مكتوب بلغة التجميع يتحول لسطر مكتوب بلغة الآلة، وهكذا -يسمى One-to-One Mapping) للجمل/السطور المخزنة في ذاكرة الحاسوب ويحولها لتعليمات وبيانات تفهمها الآلة Machine.وهذا يختلف عما يحدث في اللغات عالية المستوى، حيث يتم عادة ترجمة كل جملة إلى عدة أوامر تفهمها الآلة Machine Instructions.
وتقدم العديد من المجمعات المتطورة Assemblers إمكانيات وآليات إضافية تسهل: تطوير البرامج، التحكم في عملية التجميع، والمساعدة في اكتشاف وتصحيح الأخطاء البرمجية Debugging.وعلى وجه الخصوص، فإن معظم المجمعات الحديثة تتضمن مرفق من نوع ماكرو Macro (موصوف أدناه)، وتسمى تلك المجمعات بمجمعات ماكرو Macro Assemblers.
المفاهيم الرئيسية
المجمع Assembler
قارن مع: مجمع دقيق Microassembler.
عادة ما يقوم أي مجمع حديث بتكوين كود غرضي/نهائى Object Code عبر ترجمة تعليمات لغة التجميع إلى شفرة تشغيل Opcode (Operation Code)، وعبر تحليل الأسماء الرمزية لمواقع تخزين البيانات بالذاكرة Memory Locations وغيرها من الأشياء.ويعتبر استخدام "الإشارات الرمزية" Symbolic References سمة أساسية من سمات المجمعات، حيث يتم حفظ حسابات طويلة ومملة، وتحديث عناوين الذاكرة بعد تعديلات البرنامج.وتحتوي معظم المجمعات على تسهيلات Facilities من نواع "ماكرو" Macro تقوم بعمليات "استبدال النصوص" Textual Substitution- وعلى سبيل المثال، لتوليد متواليات قصيرة من التعليمات تعمل Inline بدلا من أن تعمل في Subroutine.
وبصفة عامة، فإن كتابة المجمعات -لأن المجمع أساسا عبارة عن برنامج Program يتم كتابته- أسهل من كتابة مترجمات اللغات عالية المستوى Compilers، وقد ظهرت المجمعات منذ خمسينات القرن الماضي.وتقوم المجمعات، وخصوصا تلك المعتمدة على بناء/هندسة حاسوبية Architecture من نوع RISC، مثل نماذج: MIPS وSPARK من شركة "صن مايكروسيستمز"، وPA-RISC من شركة "هيوليت باكارد"، وأيضا معالجات x86(-64), تقوم بالوصول لجدولة التعليمات للدرجة المثلى، من أجل استغلال خط Pipeline وحدة المعالجة المركزية أكفأ استغلال.
وهناك نوعين من المجمعات Assemblers، وتم تقسيم النوعين على أساس عدد مرات المرور Passes خلال الكودالمطلوب لإنتاج الكود النهائي، أو البرنامج القابل للتنفيذ Executable بمعنى آخر.النوع الأول، هو المجمع الذي يمر على الكود "مرة واحدة فقط"، مفترضا أن تعريف كل رموز الكود (مثل أسماء المتغيرات) سبق أي تعليمات قد تشير لهذه الرموز.النوع الثاني، وهو المجمع الذي يمر "مرتين" -أو أكثر من مرة- على الكود، ويقوم أثناء المرور الأول بتكوين جدول Table يضع فيه كل الرموز التي لم يتعرف عليها Unresolved، ويستخدم تلك الرموز في المرور الثاني 2nd Pass، كي يقوم بحل تلك العناوين Addresses.أما ميزة المجمع ذو النوع الأول "مرور واحد"، فهي "السرعة" بكل تأكيد- والتي لم تعد مهمة كما كانت يوما ما، بعد أن تطورت سرعات وإمكانيات أجهزة الكمبيوتر.أما ميزة النوع الثاني من المجمعات "تقوم بمرورين فيما فوق" فهي أن رموز البرنامج يمكن أن تعرف في أي مكان بالكود المصدري Source Code للبرنامج.
وكنتيجة لذلك، فيمكن تعريف البرنامج بطريقة أكثر منطقية وذات مغزى -على سبيل المثال، يستطيع المبرمج قراءة برامج زملاءه بسهولة أكثر-.مما يجعل برامج المجمع ثنائي-المرور أسهل في القراءة والصيانة -القيام بتعديلات عليها مثلا-.
أما المجمعات عالية المستوى وذات الإمكانيات الأكثر تعقيدا، فتوفر تجريدا أكثر للغة Abstraction، يمكن توضيحه فيما يلي:
بناءات تحكم أكثر تقدما Control Structures
إمكانية الإعلان عن وظائف/إجرائات عالية المستوى، واستدعائها.
أنواع بيانات مجردة Abstract عالية المستوى، بما في ذلك الهياكل Structures، السجلات Records، الاتحادات Unions، الأصناف Classes والمجموعات Sets.
معالجة ماكرو Macro متطورة
مميزات البرمجة غرضية التوجه Object-Oriented، مثل التغليف Encapsulation، تعدد الأشكال Polymorphism، التوريث Inheritance، الواجهات Interfaces.
لتفاصيل أخرى، انظر "تصميم اللغة" أدناه.
لاحظ أنه، في حالة الاستخدام المهني العادي، يتم استخدام اللفظ "مجمع" Assembler بشكل غامض: فكثيرا ما يتم استخدامه للإشارة للغة التجميع نفسها، بدلا من الإشارة لـ "أداة التجميع".وبالتالي: فإن عبارة "إن نموذج CP/CMS تم كتابته بلغة التجميع Assembler ذو الاسم S/360" تختلف عن العبارة "إن نموذج ASM-H لهو مجمع Assembler تم استخدامه على نطاق واسع مع S/370".
لغة التجميع Assembly
ويتكون البرنامج المكتوب بلغة التجميع من سلسلة من التعليمات-سهلة الحفظ Instructions—Mnemonics والتي تماثل دفعة من التعليمات التنفيذية Executable، وعندما يتم ترجمة هذا الكود عبر "مجمع" Assmbler"، يمكن هنا تحميل هذا الكود إلى الذاكرة وتنفيذه.
وعلى سبيل المثال، فإن معالجا Processor من نوع x86/IA-32 يمكنه تنفيذ التعليمات التالية والمكتوبة بكود ثنائي Binary يمثل لغة الآلة Machine Language (انظر لغة التجميع الخاصة بمعالج x86):
Binary: 10110000 01100001 (Hexadecimal: B0 61)
ومع قرائتك للسطر السابق تشعر بأن تمثيل الكود عبر لغة التجميع لهو أسهل للقراءة وللتذكر (مثال باستخدام تراكيب شركة إنتل، انظر استذكار
MOV AL, #61h

وتعني هذه التعليمات ما يلي:
انقل القيمة 61h (والتي تعني بالنظام العشري القيمة "97"؛ حيث تعني اللاحقة h النظام الست-عشري Hexadecimal؛ وتعني علامة الجنيه # أن يتم نقل "القيمة 97" ولا يعني أن يتم نقل "القيمة المخزنة في عنوان الذاكرة رقم 97") إلى "سجل المعالج" Register ذو الاسم AL.
الأمر "mov" يكتب بكود التشغيل بالشكل 1011, ويقوم بنقل Move القيمة المذكورة بمعامل Operand الأمر الثاني، إلى السجل المذكور عبر المعامل الأول.وقداختار "مصمم مجموعة التعليمات" تلك الحروف الثلاثة mov لتمثيل الأمر، مما يجعل الأمر سهلا على المبرمج لتذكر واستخدام الأمر.ويتم الفصل بين مجموعة  والمعطيات التي تتبع شفرة التشغيل عبر فاصلة "،"؛ إن ما سبق لهو نموذج جيد لجملة Statement من جمل لغة التجميع.
وأثناء الممارسة يقوم العديد من المبرمجين بإسقاط الكلمة Mnemonic (أمر سهل التذكر) وإطلاق وصف "كود تشغيلي" Opcode على اللفظة "mov"، وذلك خطأ تقني بكل تأكيد.فعندما يفعلون ذلك، فهم يشيرون إلى الكود الثنائي والذي تمثله لغة التجميع.ولتوضيح الأمر بشكل آخر، إن "الأمر سهل التذكر" Mnemonic مثل الأمر mov ليس كودا تشغيليا Opcode، لكنه يمثل أو يرمز إلى الكود التشغيلي، لذلك فعندما يشير أحدهم إلى "الكود التشغيلي للأمر mov" فهو يقصد إلى الإشارة للكود التشغيلي الثنائي Binary ولا يشير إلى الأمر المكتوب بلغة التجميع.وحاليا، يوجد عدد محدود من المبرمجين الذين يحتاجون للتعامل مع النماذج الثنائية التي تمثل كود التشغيل الخاص بتعليمات معينة، فهذا التمييز لم يعد يحتاجه أحد بين المبرمجين -لم تعد عملية البرمجة التي تطورت إمكانياتها تحتاجه-، لكنه مطلوبا جدا في أوساط مصممي المعالجات Processor Designers.
ويتم تحويل لغة التجميع إلى لغة الآلة عبر "المجمع" Assembler، وتتم العملية العكسية عبر برنامج يدعى "فك التجميع" Disassembler.وبخلاف اللغات عالية المستوى، فدائما ما يكون هناك توافق Correspondence بين التعليمات البسيطة المكتوبة بلغة التجميع وبين التعليمات المكتوبة بلغة الآلة.إلا أنه، وفي بعض الحالات، يمكن للمجمع أن يخرج تعلميات من نوع Pseudoinstructions، والتي يتم تمثيلها عبر "عدة" تعليمات بلغة الآلة، من أجل القيام بوظائف يشيع الاحتياج لها.وعلى سبيل المثال، بفرض أن هناك آلة ينقصها الأمر Branch-if-greater-or-equal "انتقل لمكان آخر إذا تساوت القيمة عن x أو زادت عن x" في مجموعة أوامر المجمع الخاص بها، يمكن لحل هذه المشكلة، أن يقوم المجمع بتوفير تعليمات Pseudoinstructions تجمع بين الأمرين "Set if less than" و"branch if zero" -الأمر الأخير يعمل مع ناتج الأوامر التي تسبقه-.وتوفر معظم المجمعات ذات "المميزات الكاملة" Full-Featured، لغة ماكرو Macro ثرية (والتي يتم مناقشتها أدناه) والتي يتم استخدامها من قبل الشركات Vendors والمبرمجين لإنتاج كود وتسلسل بيانات أكثر تعقيدا.
غني عن الذكر، أن كل بناء حاسوبي وكل معالج له لغة الآلة الخاصة به.
وعلى هذا المستوى، تكون كل تعليمة Instruction ممثلة بشكل بسيط بحيث يتم تنفيذها من خلال عدد صغير نسبيا من الدوائر الإلكترونية Electronic Circuits.وتختلف أجهزة الكمبيوتر باختلاف نوع وعدد العمليات التي تدعمها.وعلى سبيل المثال، فإن آلة جديده من نوع 64 بت تتكون من نوع مختلف من الدوائر التي تمتلكها آلة من نوع 32 بت.وقد يختلفان أيضا في أحجام وأعداد المسجلات Registers في كل منهما، وقد يختلفان أيضا في تمثيل البيانات داخل مخازن البيانات -المخازن مثل: الذاكرة Memory، المسجلات Registers-.وفي حين أن معظم أجهزة الكمبيوتر التي تستخدم في الأغراض العامة قادرة على تنفيذ نفس الوظائف، فإن طريقة أداء كل جهاز تختلف عن بقية الأجهزة؛ وتعكس لغات التجميع الخاصة بكل منهم هذا الاختلاف.
وقد تحتوي مجموعة واحدة من أوامر لغة التجميع "Instruction Set" مجموعات متعددة من التراكيب اللغوية التي تستخدم في كتابة الأوامر Mnemonics. وفي مثل هذه الحالات، فإن المجموعة الأكثر استخداما هي تلك التي توفرها الشركة المصنعة -للنظام الحاسوبي- وتستخدمها في وثائق منتجها Documentation.
تصميم اللغة
العناصر الأساسية
تتكون أي لغة تجميع من 3 أنواع من جمل التعليمات Instruction Statements والتي تستخدم في تعريف عمليات البرنامج:
أوامر كود التشغيل Opcode
مقاطع البيانات
توجيهات لغة التجميع Directives
أوامر كود التشغيل
عادة ما تكون التعليمات (الجمل) في لغة التجميع بسيطة للغاية، بعكس تلك الموجودة في لغات البرمجة عالية المستوى.وبصفة عامة، فإن "كود التشغيل" هو اسم رمزي لتعليمة واحدة تنفيذية مكتوبة بلغة الآلة، ويوجد على الأقل أمر واحد من الكود التنفيذي محدد لكل تعليمة مكتوبة بلغة الآلة.وكل تعليمة Instruction تتكون عادة من "عملياحد Byte، مكودة داخل التعليمة نفسها)، ويمكن أن تكون "غير مباشرة" وتشير إلى عنوان الذاكرة الذي يتم تخزين البيانات فيه.ويتحدد ذلك عبر البنية الأساسية للمعالج Architecture: فالمجمع يعبر عن كيفية عمل هذه البنية فحسب.
مقاطع البيانات
هناك تعليمات تستخدم في تحديد عناصر البيانات Data Elements التي تحمل بيانات وتحمل متغيرات.وتحدد تلك العناصر: نوعية البيانات، طول البيانات، وموائمة البيانات Alignment.ويمكن لتلك التعليمات أيضا أن تحدد إذا ما كانت تلك البيانات متاحة لبرامج خارجية Outside Programs (برامج يتم تجميعها بشكل منفصل عن البرنامج الذي يحتوي البيانات)، أو أنها متاحة فقط للبرنامج الذي يحمل قسما يحتوي تعريف تلك البيانات.
توجيهات لغة التجميع Assembly Directives/ Pseudo-Ops
"توجيهات لغة التجميع" Assembly Directives هي تعليمات يتم تنفيذها عن طريق المجمع أثناء وقت التجميع Assembly Time، ولا يتم تنفيذها عبر وحدة المعالجة المركزية CPU في وقت تشغيل البرنامج Run Time.ويمكن لتلك التوجيهات أن تجعل لغة التجميع الخاصة بالبرنامج تعتمد على "معامل" Parameter يتم إدخاله عبر المبرمج، بحيث يمكن تجميع البرنامج الواحد بأكثر من طريقة، وربما من أجل تطبيقات مختلفة -لكل نسخة مجمعة مختلفة-.ويمكن أن تستخدم "التوجيهات" Directives أيضا للتلاعب Manipulate بطريقة عرض البرنامج Presentation، مما يجعل البرنامج أسهل في القراءة والصيانة من ناحية المبرمج.
(على سبيل المثال، يمكن استخدام الـ Pseudo-Ops في حجز مساحات تخزين وملأها بقيمها المبدأية بشكل اختياري.)وغالبا ما تبدأ أسماء العمليات من نوع Pseudo-Ops بنقطة Dot لتمييزها عن باقي تعليمات الجهاز.
وتدعم بعض المجمعات أيضا تعليمات من نوع Pseudo-Instructions، والتي تقوم بتوليد تعليمتين أو أكثر من تعليمات الجهاز Machine Instructions.
وتسمح المجمعات الرمزية Symbolic للمبرمجين بتحديد أسماء من اختيارهم (علامات أو رموز) لمواقع الذاكرة Memory Locations.وعادة ما يتم إعطاء كل متغير Variable وكل ثابت Constant اسما، بحيث يمكن الإشارة لتلك العناصر داخل التعليمات بأسمائها، وبالتالي يساعد المبرمج نفسه في توثيق الكود الذي يكتبه Self-Documenting.وفي الكود القابل للتنفيذ، يتم ربط اسم كل "روتين فرعي" Subroutine بـ نقطة دخوله Entry Point، بحيث يتم استدعاء الروتين الفرعي عبر استخدام اسمه.وداخل الروتينات الفرعية، يتم إعطاء علامات Labels لوجهات الأمر GOTO.وتدعم بعض المجمعات "رموزا محلية" Local Symbols والتي تختلف مفرداتها عن الرموز العادية (مثال: استخدام التركيب "10$" كوجهة للأمر GOTO).
وتوفر معظم المجمعات إدارة مرنة للرموز، بحيث تتيح للمبرمجين: إدارة مساحات إسمية مختلفة Namespaces، حساب الإزاحات بشكل آلي داخل هياكل البيانات Data Structures، وتحديد تسميات/علامات Labels تشير إلى قيم حرفية أو إلى ناتج حسابات بسيطة تؤدى عبر المجمع.وتستخدم التسميات/العلامات Labels أيضا لتهيئة الثوابت Constants والمتغيرات Variables مع عناوين قابلة للإعادة التعيين Relocatable Addresses.
ومثلها مثل معظم لغات الكمبيوتر الأخرى، تسمح لغات التجميع بإضافة "تعليقات" Comments إلى كود المصدر، وتتم تجاهل هذه التعليقات عن طريق "المجمع" -أي لا تتم ترجمتها للغة الآلة بالطبع-.ويعد استخدام التعليقات بشكل جيد مع كود لغة التجميع أكثر أهمية من استخدام التعليقات مع اللغات عالية المستوى، لأنه من الصعب استنباط معنى ومغزى سلسلة تعليمات لغة التجميع عبر قراءة الكود فقط -دون تعليقات توضحه-.
ويمكن لحسن استخدام تلك التسهيلات Facilities أن يبسط جدا من مشكلات عمليات التكويد والصيانة الخاصة بكود اللغات منخضفة المستوى Low-Level.
وإذا دعت الحاجة لتغييره فإن من الصعب جدا قراءة كود لغة التجميع الخام Raw - والذي يتم توليده عبر مترجمات Compilers أو برامج فك التجميع Disassembler-، حيث يتكون من مجموعة تعليمات متراصة، بدون أي تعليقات، بدون أي رموز لها مغزى، وبدون أي تعريفات للبيانات.
وحدات الماكرو Macros
تدعم العديد من المجمعات وحدات الماكرو Macros، وهي عبارة عن رموز معرفة عن طريق المبرمج وتحوي مجموعة من سطور النص المتسلسلة.هذا التسلسل للسطور النصية، قد يحوي سلسلة من التعليمات، أو سلسلة من تعليمات Pseudo-Ops خاصة بالبيانات.وطالما تم تعريف الماكرو عبر استخدام الـ Pseudo-Op المناسب، فإنه من الممكن استخدام اسمه، مثلما يتم استخدام أسماء الأوامر Mnemonic تماما.وعندما يقوم المجمع بمعالجة جملة Statement من تلك النوعية، فإنه يقوم باستبدال الجملة -التي تحوي اسم الماكرو- بالسطور النصية المرتبطة بذلك الماكرو، وبعد ذلك يقوم بمعالجة تلك السطور كما لو أنها قد ظهرت في ملف كود المصدر (متضمنا، كما يحدث مع المجمعات الجيدة، محتويات أي ماكرو قد يظهر في تلك السطور -ماكرو داخل ماكرو-).
وبما أن وحدات الماكرو يمكن أن تحمل أسماء "قصيرة" وفي نفس الوقت تحمل سطورا طويلة من الكود، فإن وحدات الماكرو يمكن أن تستخدم لتجعل البرامج المكتوبة بلغة التجميع تبدو وكأنها أقصر (بمعنى أن يتطلب بناء التطبيق عددا أقل من سطور الكود، كما هو الحال مع لغات البرمجة عالية المستوى).ويمكن أيضا أن يتم استخدامها لإضافة هياكل Structures عالية المستوى إلى البرامج المكتوبة بلغة التجميع، ويمكن أن تقدم -بشكل اختياري- كود يستخدم لإدارة وإصلاح الأخطاء De-Bugging بشكل ضمني، عبر المعاملات Parameters وعبر خصائص أخرى.
معظم المجمعات تمتلك وحدات ماكرو مدمجة Built-in من أجل الاستدعائات عبر النظام System Calls ومن أجل بعض تسلسلات الكود الخاصة.
وغالبا ما تسمح المجمعات لوحدات ماكرو بأن تمتلك معامالات Parameters.وبعض المجمعات تمتلك لغة ماكرو معقدة جدا، وتقوم بدمج عناصر هذه اللغة عالية المستوى للقيام بوظائف متعددة: معاملات اختيارية Optional Parameters، متغيرات رمزية، جمل شرطية، معالجة لسلاسل الحرفية Strings، عمل عمليات حسابية، وجميع تلك الأشياء يمكن إعادة استخدامها أثناء تنفيذ وحدات ماكرو بعينها، وتسمح -تلك المجمعات- لوحدات الماكرو بحفظ السياق Context أو تبادل المعلومات بين بعضها البعض.ولذلك، فإن الماكرو يمكنه توليد عدد ضخم من تعليمات لغة التجميع أو من تعريفات البيانات، استنادا إلى معاملات الماكرو Arguments.ويمكن استخدام ذلك لتوليد هياكل بيانات ذات شكل "سجلي" Record-Style، ويمكن استخدام ذلك أيضا لتولييد دوارات Loops مبسوطة Unrolled، هذا على سبيل المثال، ويمكن أيضا استخدام نفس التقنية في توليد خوارزميات كاملة Algorithms تستند على معاملات معقدة Parameters.ويمكن اعتبار مؤسسة تستخدم هذه النوعية من لغات التجميع والتي تم تمديد قدراتها بشكل مكثف عبر استخدام مجموعة وحدات الماكرو، يمكن اعتبارها وكأنها تستخدم لغة برمجة عالية المستوى، حيث أن مبرمجي الشركة لا يعملون مع عناصر الكمبيوتر المفاهيمية ذات المستوى المنخفض -مثال: لا يعملون مع المسجلات مثلا Registers-.
وقد تم استخدام وحدات الماكرو في عهد الحاسب الكبير Mainframe من أجل تخصيص Customize نظم برمجية واسعة النطاق Large Scale لتلبية طلبات محددة لعملاء معينين، واستخدت أيضا عبر فريق عمل أحد العملاء من أجل تلبية احتياجات موظفيه عبر بناء نسخ محددة من نظم تشغيل مصنع الكمبيوترات Manufacturer-الذي قد اشتراها هذا العميل-، وعلى سبيل المثال، فقد سبق فعل ذلك، مع مبرمجي النظم الذين كانوا يعملون لشركة IBM، وبشكل أكثر تحديدا، كانوا يعملون على نظام مراقبة المحادثات/ النظام الافتراضي CMS/VM، وعلى نظام "معالجة المعاملات بشكل لحظي Real Time"، وعلى نظام "التحكم في بيانات العملاء"، وعلى ACP/TPF، وهو نظام مالي إداري -خاص بخطوط الطيران- بدأ في السبعينات وما زال يقوم بتشغيل نظم عالمية كبرى للتوزيع GDS ونظم بطاقات الائتمان حتى يومنا هذا.
وكان من الممكن أيضا أن يتم استخدام قدرات الماكرو المعالجة Processing فقط بحيث يقوم المجمع بتوليد كود مكتوب بلغات مختلفة تماما، وعلى سبيل المثال، يمكن استخدام تلك التقنية في توليد نسخة من البرنامج مكتوبة بلغة "كوبول" Cobol عبر استخدام مجمع مزود ببرنامج ماكرو يحتوي على سطور من كود الكوبول، وأثناء وقت التجميع Assembly Time يمكن لمعاملات Operators أن توجه المجمع لتوليد الكود بشكل تحكمي Arbitrary.
ويرجع سبب ذلك، كما تم إدراكه في السبعينات، أن مفهوم "معالجة الماكرو" Macro Processing يختلف عن مفهوم "التجميع" Assembly، حيث يشير المصطلح الأول في لغتنا الحاسوبية الحديثة إلى إمكانيات في برامج معالجة الكلمات، معالجة النصوص، أكثر من إشارته إلى توليد الكود.وحقيقة، فإن مفهوم "معالجة الماكرو" قد ظهر -وما زال يظهر- في لغة البرمجة "سي" C، حيث تدعم "تعليمات ما قبل المعالجة" Preprocessor Instructions من أجل تحديد قيم المتغيرات Set Variables.لاحظ أنه على عكس الأنواع المحددة لمعالجات الماكرو التي تم ذكرها والتي تعمل داخل المجمعات، فإن المعالج القبيل للغة الـ C لم يكن Turing-Complete (متكامل مع معايير تورنغ) لأنه كان ينقصه إمكانية "الدوارات" Loops أو الذهاب إلى تعليمة محددة عبر أمر Go To.
وبالرغم من قوة معالجة الماكرو، فقد تم إهمالها في اللغات عالية المستوى، بينما تظل مهمة وموجودة في المجمعات Assemblers.
وذلك يرجع إلى الحيرة والارتباك التي وقع فيهما العديد من المبرمجين، حيث شكل لهم "تعويض معاملات" الماكرو مشكلة، ولم يستطيعوا فك الخلط بين معالجة الماكرو أثناء التجميع وأثناء التنفيذ.
ويتم استبدال معاملات الماكرو Parameter Substitution بشكل صارم عبر الاسم فقط: في وقت معالجة الماكرو، يتم استبدال قيمة المعامل باسم المعامل نصيا.وينتج أشهر صنف من الأخطاء Bugs عبر استخدام المعامل والذي كان يعبر -نفسه- عن Expression وليس عن اسم بسيط، في حين أن كاتب الماكرو يتوقع اسما Name.وفي الماكرو:

foo: macro a

load a*b


القصد هنا هو أن يقوم المنادي Caller بتوفير اسم للمتغير، ويتم ضرب المتغير "العالمي" Global أو الثابت "b" في "a".إذا تم استدعاء foo مع المعامل a-c، سيقوم الماكرو بالتوسع Expand بشكل غير متوقع.
ولتجنب هذا الأمر، تعلم مستخدمو "معالجة الماكرو" أن يقوموا بحصر المعاملات داخل تعريفات الماكرو Macro Definitions، ثم يكون على المناديين Callers أن يفعلوا المثل مع معاملاتهم "الحقيقية" Actual Parameters.
وقد قدمت لغات الـ PL/I وC ميزة الماكرو، لكن تلك التسهيلة Facility كانت خطرة ولم تستخدم بشكل كافي لأنها لم تكن تعالج سوى النصوص Text.ومن ناحية أخرى، حافظ لغات الذكاء الصناعي Homoiconic مثل Lisp وProlog وForth على إمكانيات ماكروهات Macros لغات التجميعات خاصتها، لأنهم جميعا قادرين على معالجة الكود الخاص بهم مثلهم مثل البيانات.
دعم البرمجة المهيكلة Structured
قامت بعض المجمعات بإدماج عناصر البرمجة المهيكلة من أجل تكويد Encode تدفق التنفيذ Execution Flow.وأقرب مثال لهذا النهج كانت مجموعة ماكرو المسماة Concept-14, والتي اقترحت لأول مرة عن طريق الدكتور هـ.د.ميلز(مارس 1970), وتم تنفيذها عبر مارفين كيسلر في قسم الأنظمة الفيدرالية بـ IBM، والتي مددت إمكانيات مجمع الماكرو من نوع S/360 بـ IF/ELSE/ENDIF وبلوكات أخرى للتحكم في التدفق Flow Control.وقد كانت تلك طريقة لخفض أو إزالة استخدام عمليات GOTO في كود التجميع، حيث أن عمليات الـ GOTO من العوامل الرئيسية التي تسبب في ما يسمى بـ "كود الإسباجتي" -الكود المتشابك والمتعقد- في لغة التجميع.وقد كانت هذه الطريقة مستخدمة ومقبولة على نطاق واسع في أوائل الثمانينات (والتي شكلت الأيام الأخيرة لاستخدام لغة التجميع على نطاق واسع، لم يعد الأمر كذلك الآن).
وقد تم تقديم تصميم غريب سمى A-Natural، وهو عبارة عن مجمع من نوع Stream-Oriented يعمل مع معالجات 8080/Z80 وصممته شركة Whitesmiths Ltd. (تلك الشركة التي طورت نظام التشغيل الشبيهة بيونيكس والمسمى Idris، والذي وصف بأنه أول مترجم تجاري للغة السي C).وقد صنفت اللغة كمجمع Assembler، لأنها كانت تعمل مع عناصر الماكينة "الخام" Machine Elements مثل كود التنفيذ Opcodes، المسجلات Registers، ومراجع الذاكرة References؛ ولكنها أدرجت جملا تعبيرية Expression Syntax للإشارة إلى ترتيب التنفيذ.وقد قامت: الأقواس Parentheses، والرموز الخاصة الأخرى، بجانب الـ Constructs الخاصة بالبرمجة المهيكلة المعتمدة على بلوكات Blocks، قام كل ذلك بالتحكم في تتابع توليد التعليمات Instructions.وقد تم بناء لغة A-Natural لتصبح مترجما Compiler خاص بلغة الـ C، أكثر من بنائها لكي يتم استخدامها في البرمجة اليدوية، لكن جملها المنطقية Syntax أعجبت العديد من المبرمجين الذين عملوا بها وكتبوا بها برامج بالفعل.
وقد ظهرت الحاجة والطلب إلى مترجمات أكثر تعقيدا بعد أن انحدر تطوير البرمجيات باستخدام لغات التجميع على نطاق واسع Large-Scale.وعلى الرغم من ذلك، فإن تلك المجمعات لا تزال تستخدم في بعض الحالات، والتي تحوي قيودا مفروضة على الموارد -وقت، نفقات..الخ- أو أن الخصوصيات Peculiarities المتعلقة بهندسة النظام -الخاص بالتطبيق الجاري تطويره- تمنع الاستخدام الكفؤ للغات البرمجة عالية المستوى.
استخدام لغة التجميع
نظرة تاريخية
تم تطوير لغة التجميع لأول مرة في الخمسينيات من القرن المنصرم، وقد تم الإشارة لتلك اللغات في هذا الحين على أنها "الجيل الثاني" من لغات البرمجة.وقد محت لغات الجيل الثاني الكثير من مشكلات منح-الأخطاء Error-Prone ومشكلات استهلاك الوقت التي اتصفت بها لغات البرمجة من "الجيل الأول" التي تعاملت مع الأجيال الأولى من أجهزة الكمبيوتر، وقد حررت اللغات الجديدة المبرمجين من الكثير من الأمور المملة مثل تذكر الرموز الرقمية وحساب عناوين الذاكرة.وقد استخدمت تلك اللغات يوما ما وبشكل واسع في جميع أنواع البرمجة.وعلى الرغم من ذلك، فإن مع الثمانينات (ومع التسعينات على الحواسب الصغيرة)، فقد استبدلت تلك اللغات بشكل واسع بلغات البرمجة عالية المستوى high-Level Languages، في البحث عن المزيد من التحسين لـ "إنتاجية" العمل البرمجي.واليوم، تستخدم لغة التجميع بشكل رئيسي في: التحكم المباشر في الأجهزة Hardware، الوصول إلى تعليمات المعالج المتخصصة Processor Instructions، أو لمعالجة مسائل حاسمة تتعلق بالسرعة/الأداء Performance.ومن الأنظمة التي تستخدم عادة لغات التجميع، تجد: مشغلات الأجهزة Device Drivers، النظم المطمرة Embedded Systems منخفضة المستوى، وأنظمة الوقت الحقيقي Real-Time.
وتاريخيا، فقد تم كتابة عدد كبير جدا من البرامج بشكل كلي باستخدام لغة التجميع.وقد تم كتابة بعض أنظمة التشغيل Operating Systems بلغة التجميع وبشكل حصري Exclusively، حتى تم انتشار لغة السي C بشكل واسع في فترة السبعينات وأوائل الثمانينات.وقد تم كتابة العديد من التطبيقات التجارية باستخدام لغة التجميع كذلك، ومنها كميات كبيرة من برمجيات تم كتابتها بواسطة شركات كبرى لتعمل على الحواسب الكبيرة Mainframes الخاصة المصنعة عبر شركة IBM.وعلى الرغم أنه -في نهاية الأمر- قامت لغات "كوبول" COBOL و"فورتران" FORTRAN باستبدال معظم هذا العمل، إلا أن عدد كبير من المنظمات/الشركات حافظت على نظمها وبنيها التحتية Infrastructure المبرمجة عبر لغة التجميع حتى التسعينات، حيث عملت طول هذه الفترة بشكل جيد.
وقد اعتمدت معظم الحواسيب الصغيرة Microcomputers على كود مكتوب يدويا باستخدام لغة التجميع، بما في ذلك نظم التشغيل Operating Systems والتطبيقات الكبيرة.وذلك لعدة أسباب: أولها أن تلك النظم حافظت على قيود شديدة على الموارد، فرضت خصوصية على الذاكرة Memory وعلى عرض بنية التطبيقات Architecture، وخفضت من نسبة الأخطاء Bugs التي تظهر أثناء عمل النظم.وربما كان الأهم من ذلك كله كانت الحاجة لوجود مترجمات للغة عالية المستوى من الدرجة الأولى First-Class، تكون مناسبة لاستخدام الحواسيب الصغيرة Microcomputers.وقد يكون هناك عاملا نفسيا قد لعب دورا أيضا: أن الجيل الأول من مبرمجي الحواسيب الصغيرة ظلوا يحتفظون بموقف الهواة Hobbyists والذي يمكن صياغته في العبارة: "الأسلاك والزرديات" Wires and Pliers -عبارة تشير إلى تمسك أولئك المبرمجين بالأسلوب "الصعب" للغة التجميع على الرغم من توافر أساليب "أسهل" مثل اللغات عالية المستوى-.
وفي اطار تجاري أكثر، فإن الأسباب الرئيسية لاستخدام لغة التجميع كانت: حجم Size أقل، مشكلات Overhead أقل، سرعة أعلى واعتمادية Reliability أعلى.
وكأمثلة نموذجية لبرامج كبرى كتبت بلغة التجميع في ذاك الوقت، تجد نظام التشغيل "مايكروسوفت دوس" MS-DOS، وبرنامج IBM لمعالجة الجداول "لوتس" Lotus 1-2-3, وكذلك معظم الألعاب الشهيرة لعائلة "الأتاري" Atari 800 للحواسب المنزلية.وحتى في التسعينات، معظم ألعاب الفيديو من نوع Console تم كتابتها عبر لغة التجميع، بما في ذلك معظم ألعاب شركات Mega Drive/Gensis وشركة Super Nintendo لأنظمة الترفيه.ووفقا لبعض المطلعين داخل صناعة البرمجيات، فإن لغة التجميع كانت أفضل لغة حوسبة يمكن استخدامها من أجل أداء/سرعة عاليين لأجهزة Sega Saturn -وهي أجهزة Console كانت تشتهر في مجال تطوير وبرمجة الألعاب-.وكذلك لعبة NBA Jam والتي ظهرت عام 1993 كلعبة من نوع Arcade ونالت شعبية كبيرة، تعتبر مثالا آخر.واعتبرت لغة التجميع هي لغة التطوير الأساسية على عدة منصات لوقت طويل، منها: Commodore 64، Atari ST وكذلك حواسب المنزل من نوع ZX Spectrum.وقد تسببت عدم كفاءة لغة الـ BASIC -في ذلك الوقت- في استمرار اعتماد تلك الآلات على لغة التجميع، لقد عاب الـ BASIC سببين: لم يوفر سرعة تنفيذ عالية مع هذه النظم، لم يقدم تسهيلات كافية من أجل أفضل استخدام لإمكانيات العتاد Hardware الخاصة بتلك النظم.بعض الأنظمة، وعلى الأخص Amiga، لديها "بيئة تطوير متكاملة" IDE مع إمكانيات عالية لاكتشاف ومعالجة الأخطاء Debugging وإمكانيات "ماكرو"، مثل المجمع المجاني ASM-One، مقارنة بإمكانيات برنامج Microsoft Visual Studio (على الرغم من أن ASM-One يسبق Microsoft Visual Studio من حيث وقت الإصدار).
وقد تم كتابة المجمع VIC-20 عبر "دون فرينش" ونشرته شركة "فرينش سيلك".وقد تم كتابته في برنامج يبلغ من الحجم 1639 بايتس Bytes فقط، مما يجعل صاحبه يعتقد أنه أصغر مجمع رمزي تم كتابته في التاريخ.ويدعم المجمع نظم العنونة الرمزية والتعريفات الخاصة بسلاسل الحروف وسلاسل الرموز ذات النظام الـHexadecimal.ويسمح المجمع أيضا بتعيرات العناوين Address Expressions والتي يمكن توحيدها Combined مع عمليات: الجمع، الطرح، الضرب، القسمة، Logical AND, Logical OR والمعاملات الأسية ExponentiationOperators.
الاستخدام الحالي
دائما ما كان هناك جدلا حول فائدة وأداء لغة التجميع بالمقارنة بلغات البرمجة عالية المستوى.ومعروف أن لغة التجميع لها اطار محدد Niche تظهر فيه أهميتها؛ انظر أدناه.ولكن بصفة عامة، تدعي المترجمات Compilers الحديثة المثلى Optimized أنها تستطيع معالجة كود لغات البرمجة عالية المستوى وتستطيع تنفيذه Run بنفس سرعة تنفيذ الكود المكتوب يدويا بلغة التجميع، على الرغم من بعض الأمثلة العكسية Counter-Examples التي يمكن أن تنشأ.وتشكل زيادة تعقيد المعالجات الحديثة صعوبات متزايدة في كتابة كود فعال محسن يدويا Hand-Optimized.وعلاوة على ذلك، ولاستياء عشاق الكفاءة Efficiency، فإن زيادة أداء/سرعة المعالج تعني أن معظم وحدات المعالجة المركزية CPUs تظل خاملة Idle معظم الوقت، بسبب التأخيرات الناجمة عن اختناقات Bottlenecks يمكن التنبؤ بها Predictable مثل عمليات الإدخال/الإخراج I/O وعمليات الـ Paging.ذلك مما جعل العديد من المبرمجين يتوقفون عن اعتبار سرعة تنفيذ الكود الخام أمرا مهما.
وهناك بعض الحالات التي قد يختار فيها الممارسون استخدام لغة التجميع، مثل الحالات التالية:
عند الحاجة لبرنامج تنفيذي ثنائي Binary قائم بذاته Stand-Alone، بمعنى: برنامج يجب أن يتم تنفيذه بدون اللجوء إلى مكونات Components أو مكتبات Libraries مرتبطة بلغة برمجة عالية المستوى أثناء وقت التنفيذ Run-Time؛ وربما يكون هذا الوضع هو الأكثر شيوعا.وهذه أنواع مدمجة Embedded من البرامج، والتي تقوم بتخزين جزء صغير فقط من الذاكرة ويقوم الجهاز Device بتنفيذ مهام ذات غرض واحد Single Purpose.من تلك الأمثلة، تجد: الهواتف، أنظمة الوقود/إشعال الوقود في السيارات، أنظمة التحكم في تكييف الهواء، أنظمة الأمن وأجهزة الاستشعار.
التفاعل المباشر مع الأجهزة Hardware، وعلى سبيل المثال في مشغلات الأجهزة Drivers ومعالجات الاعتراضات Interrupt Handlers.
استخدام تعليمات خاصة بالمعالج Processor-Specific، غير متوفرة للمترجم Compiler.ومن الأمثلة الشائعة على ذلك، تعليمة الدوران في اتجاه البت Bitwise Rotation، والتي تستخدم في العديد من خوارزميات التشفير Algorithms.
عند الحاجة لتحسين شديد Extreme Optimization، ومثال على ذلك: في دوارة داخلية Inner Loop في خوارزمية تستهلك المعالج بشكل كثيف.ويستفيد مبرمجو الألعاب من الإمكانيات الخاصة بخصائص العتاد Hardware في تلك الأنظمة، مما يمكن ألعابهم لتعمل بشكل أسرع.
في حالة وجود نظام ذو قيود شديدة على الموارد Resource Constraints (مثال: الأنظمة المطمرة Embedded Systems)، لذلك وجب استخدام كود مكتوب يدويا لتحقيق الاستفادة القصوى من الموارد المحدودة، ولكن ذلك يصبح أقل شيوعا مع انخفاض أسعار المعالجات وتحسن مستوى الأداء/السرعة.
في حالة عدم وجود لغة عالية المستوى -على سبيل المثال: على معالج Processor خاص أو جديد-.
في كتابة برمجيات من نوع "الزمن الحقيقي" Real-Time والتي تحتاج توقيتا دقيقا واستجابات دقيقة Responses، مثل برامج المحاكاة Simulation، نظم الملاحة الجوية والمعدات الطبية.وعلى سبيل المثال، في نظام التحكم في الطيران من نوع Fly-by-Wire، يجب ترجمة القياس عن بعد Telemetry واتخاذ إجراءات على أساس هذا القياس في ظل قيود زمنية صارمة -في أجزاء ضئيلة جدا من الوحدات الزمنية-.ويجب على تلك الأنظمة أن تتخلص من أي تأخيرات لا يمكن التنبؤ بهاو والتي قد تنشأ عبر لغات البرمجة المترجمة Interpreted، أو عبر الجمع الآلي للقمامة Garbage Collection، عمليات الـ Paging، أو تعدد المهام بشكل وقائي Preemptive Multitasking.وعلى الرغم من ذلك، فإن بعض لغات البرمجة عالية المستوى تقوم بإدماج مكونات من نوع Run-Time وإدماج واجهات لنظم التشغيل OS Interfaces والتي يمكنها أن تسبب مثل هذا التأخير Delay.وهنا يعتبر اختيار لغة التجميع أو أي لغة منخفضة المستوى Lower-Level اختيارا جيدا مما يعطي المبرمج وضوح Visibility أكبر وسيطرة أفضل على تفاصيل المعالجة Processing.
في حالة الحاجة إلى تحكم كامل في البيئة المحيطة Environment، في المواقف التي تتطلب اجراءات أمنية مشددة حيث لا يمكن أخذ أمر على أنه مفروغا منه Taken for Granted.
لكتابة فيروسات كمبيوتر، برامج من نوع Bootloaders، مشغلات لأجهزة بعينها، أو لأشياء أخرى تعمل بشكل قريب من العتاد Hardware أو من نظام تشغيل مكتوب بلغة منخفضة المستوى.
لعمل هندسة عكسية Reverse-Engineering لأكواد ثنائية موجودة، والتي قد تكون أو قد لاتكون كتبت بشكل أصلي عبر لغة برمجة عالية المستوى، وعلى سبيل المثال: في حالة اختراق Cracking حماية النسخة الخاصة ببرنامج محمي وله حقوق ملكية Proprietary Software.
عمل هندسة عكسية وتعديل ألعاب الفيديو (معروف أيضا باسم ROM Hacking)، والذي يمكن عمله عبر عدة تقنيات.والطريقة الأكثر استعمالا هي تبديل كود البرنامج على مستوى لغة التجميع.
كتابة كود يقوم بتعديل نفسه Selfmodifying، وتبرع لغة التجميع في مثل هذا الأمر.
كتابة برامج الألعاب والتطبيقات الأخرى التي تتضن حسابات رسومية Graphing.
كتابة برنامج لمترجم Compiler يقوم بتوليد كود تجميعي، وبالطبع سيكون كاتب (كتاب) هذا البرنامج من المتخصصين في البرمجة بلغة التجميع.
ومع ذلك، فإنه يتم تدريس لغة التجميع حتى يومنا هذا في معظم مناهج الهندسة الإلكترونية وعلوم الحاسب.على الرغم من أن هناك قلة قليلة من المبرمجين اليوم يعملون بشكل منتظم مع لغة التجميع بوصفها أداة تطوير، فإن المفاهيم المرتبطة بلغة التجميع لا تزال مهمة جدا.ومن تلك المواضيع الأساسية: الحساب الثنائي Binary Arithmetic، تخصيص الذاكرة Allocation، معالجة المكدس Stack، تكويد مجموعة الأحرف Character Set، معالجة المقاطعات Interrupts، وتصميم المترجمات Compilers، كل تلك الأشياء سيكون من الصعب جدا فهمها دون فهم كيفية عمل الكمبيوتر على مستوى العتاد Hardware.ولأن سلوك الكمبيوتر يمكن تعريفه عبر مجموعة التعليمات Instruction Set الخاصة به، فإن الطريقة المنطقية لتعلم مجموعة المفاهيم المرتبطة بهذا "السلوك" هي دراسة لغة التجميع.وتمتلك معظم الأجهزة الحديثة مجموعة تعليمات مماثلة.ولذلك، فإن دراسة لغة تجميع واحدة تكفي لتعلم الآتي: (1) المفاهيم الرئيسية, (2) للتعرف على المواقف التي يكون فيها من المناسب استخدام لغة التجميع, (3) لمعرفة كيف يمكن توليد كود تنفيذي كفؤ من اللغات عالية المستوى.
التطبيقات العملية
غالبا ما يتم استخدام الكود المكتوب بلغة التجميع في نظام ROM عند تحميل النظام (BIOS على نظم PC المتوافقة مع IBM) - كلمة BIOS اختصارا لـ Basic Input Output System-.ويستخدم هذا الكود المكتوب بلغة منخفضة المستوى، مع أشياء أخرى، في تهيئة واختبار العتاد Hardware قبل تحميل نظام التشغيل OS، ويخزن ذلك الكود في الذاكرة من نوع القراءة فقط ROM -اختصار Read Only Memory-. وحالما تم الوصول لمستوى معين من تهيئة الجهاز، يتم الانتقال إلى تنفيذ كود آخر، وغالبا ما يكون مكتوبا بلغة عالية المستوى؛ لكن الكود الذي يتم تشغيله بعد الضغط على زر تشغيل الكمبيوتر Power Button غالبا ما يكون مكتوب بلغة التجميع.ونطبق نفس الشئ على معظم برامج التحميل Boot Loaders.
وتقوم معظم المترجمات Compilers بمعالجة لغات عالية المستوى إلى لغة تجميع أولا قبل الترجمة النهائية، وبذلك تتيح كود التجميع ليتعرض لعمليات التصحيح Debugging والتحسين Optimization.وتوفر لغات البرمجة منخفضة المستوى نسبيا، مثل لغة السي C، بناء لغويا خاصا Syntax لدمج الكود المكتوب بلغة التجميع مباشرة في كود المصدر الخاص بها.ويمكن للبرامج التي تستخدم مثل هذه التسيهلات، كـ Linux Kernel (نواة لينكس) على سبيل المثال، أن تبني تجريديات Abstractions عبر استخدام عدة لغات تجميع على كل منصة عتادة مختلفة Hardware Platform.ويمكن للكود النقال Portable الخاص بالنظام أن يستخدم المكونات الخاصة بكل معالج -للعمل مع مختلف المنصات- خلال واجهة Interface موحدة.
وتعد لغة التجميع شيئا ذي قيمة كبيرة مع "الهندسة العكسية" Reverse Engineering، لأن العديد من البرامج يتم تداولها في صيغة كود آلة Machine Code، وغالبا ما يكون "كود الآلة" سهلا في الترجمة إلى لغة التجميع ويختبر بعناية في هذا الشكل، أما تحويله إلى لغة عالية المستوى لهو أمر صعب للغاية.وتستخدم أدوات مثل "المفكك التفاعلي" Interactive Disassembler نفس التقنية على شكل واسع من أجل نفس الأهداف.
هناك أيضا الدموسين والذي يجعل من استخدام لغة التجميع حقلا فريدا له.فهناك العديد من المسابقات الخاصة التي تقيد المتسابقين بتقييد إبداعاتهم -من البرامج- إلى حجم صغير جدا (أمثلة: 256 بايت, 1 كيلو بايت, 4 كيلو بايت أو 64 كيلو بايت)، وبالطبع فإن لغة التجميع هي أمثل حل لتحقيق هذا الهدف.وعندما يكون الحفاظ على الموارد Resources، وخاصة وحدة المعالجة المركزية CPU للأنظمة التي تفرض قيودا على المعالجة Processing، مثل النماذج السابقة لأجهزة Amiga وأجهزة Commodore 64, هنا تصبح البرمجة بلغة التجميع أمرا لا بد منه: حيث يتم كتابة كود التجميع "يدويا" ويتم إعداد تسلسل التعليمات عبر المبرمجين في محاولة لخفض عدد دورات الـ CPU المستخدمة؛ لأن القيود المفروضة على الـ CPU غاية في الصرامة، لدرجة أن كل دورة للـ CPU يحب وضعها في الحسبان.ومع ذلك، فإن الفضل يرجع لاستخدام مثل تلك التطبيقات والتي أتاحت نظما مثل Commodore 64 أن ينتج رسوميات ثلاثية الأبعاد 3D Graphics تعمل في نمط "الزمن الحقيقي" Real-Time، مع تأثيرات متقدمة Effects، وهو الإنجاز الذي قد يعتبر تحقيقه بعيد الاحتمال على أجهزة حديثة ومتطورة مع معالج 0.99 ميجا هيرتز.
المصطلحات ذات الصلة
عادة ما يطلق على "لغة التجميع" أو "لغة المجمع" الأسماء التالية: assembly, assembler, ASM أو symbolic machine code.وقد أطلق عليها بعض المبرمجين من أجيال الحاسب الكبير IBM Mainframe اسم BAL ويعود اختصار الاسم للجملة "لغة التجميع الأساسية" Basic Assembly Language.

ملاحظة: إطلاق اسم "مجمع" Assembler على "اللغة" هو بالطبع أمر مربك وغامض، لأن "المجمع" هو البرنامج الذي يقوم بتحويل الكود المكتوب بلغة التجميع إلى كود الآلة Machine Code.وقد يرى البعض هذا الأمر على أنه خطأ، وينقصه الدقة.وعلى الرغم من ذلك، فإن ذلك اللفظ شاع استخدامه بين المتخصصين والكتاب على مدى عقود.وبشكل مشابه، قام مصمموا بعض أجهزة الكمبيوتر بإطلاق اسم "المجمع" Assembler على "برنامج التجميع" الخاص بهم Assembly Program.
عند عمل المجمع، فإن الخطوة الحسابية التي يقوم بها، والتي تتضمن كل عمليات معالجة الماكرو، تسمى بـ "وقت التجميع" Assembly Time.
يرجع المسمى "تجميع" Assembly إلى السنوات الأولى لظهور الكمبيوتر (راجع. الكود القصير short code، الكود السريع speed code).
المجمع العابر Cross Assembler (انظر المترجم العابر Cross Compiler) تشبه وظيفته وظيفة المجمع.لكن تم إطلاق هذا المصطلح عليه، للإشارة أن المجمع يعمل على جهاز كمبيوتر مختلف، عن ذلك الذي سيتم تنفيذ الكود الناتج عليه: الكمبيوتر المستهدف Target System.ولأنه، في الوقت الحاضر، يتم كتابة المجمعات بشكل "متنقل" Portable وبلغات عالية المستوى مثل لغة السي C، فإن المجمعات الحالية لا تمت لذلك الموضوع بصلة.فأهمية المجمع العابر تظهر بشكل جلي إذا احتاج النظام المستهدف Target System إلى إمكانية تشغيل "المجمع" بنفسه.وهذا هو الحال عادة مع الأنظمة المطمرة الصغيرة Embedded Systems.وكذلك، فإن أهم ملمح مميز للـ "مجمع العابر" هو أنه يوفر واجهات Interfaces تسهل من نقل الكود إلى المعالج المستهدف Target Processor، بمعنى: أن يكون على ذاكرة Flash أو EPROM. ويقوم بتوليد صورة ثنائية Binary Image أو ملف من نوع Intel Hex بدلا من أن يقوم بتوليد ملف مستهدف Object File.
الـ "توجيه المجمع" Assembler Directive، هو أمر Command يتم توجيهه إلى المجمع.وقد تؤدي هذه الموجهات أي شيء، مثل إخبار المجمع بأن يدمج مع البرنامج ملفات كود أخرى Source Files، أو يخبر البرنامج بتخصيص أماكن معينة في الذاكرة لتحمل بيانات ثابتة Constants.
قائمة بالمجمعات الخاصة بالهندسات  Architectures المختلفة للكمبيوتر
تحتوي الصفحة التالية على قائمة بأنواع مختلفة من المجمعات التي تعمل مع هندسات/أبنية مختلفة من الحواسب، وتحوي القائمة معلومات مرتبطة بكل نوع من أنواع تلك المجمعات:
قائمة بالمجمعات Assemblers
مزيد من التفاصيل
لقد تم كتابة ما لا يقل عن عشرات من المجمعات لكل كمبيوتر شخصي، حاسب كبير Mainframe، نظام مطمر Embedded System ولعبة كونسول Console Game، في الماضي والحاضر. ولمطالعة بعض الأمثلة، راجع قائمة المجمعات Assemblers.
وعلى أنظمة يونيكس Unix، غالبا ما يطلع على المجمع التقليدي اسم as، على الرغم من أنه ليس كيان واحد من الكود، لأنه يجري عادة كتابة مجمع جديد لكل بورت Port.وهناك العديد من اصدارات يونيكس Unix تستخدم GAS.
لكل مجمع لهجة خاصة Dialect، داخل مجموعة من المجمعات.وأحيانا، تستطيع بعض المجمعات قراءة اللهجة الخاصة بمجمع آخر، وعلى سبيل المثال، يمكن لمجمع TASM من قراءة كود الـ MASM القديم، لكن العكس ليس صحيحا.ويمتلك مجمعي الـ FASM والـ NASM بناء لغوي متشابه Syntax، لكن كلا منهم يدعم مجموعة مختلفة من الماكرو Macro مما يجعل من الصعب الترجمة من أحدهم للآخر.وبالطبع فإن الأساسيات تظل واحدة، لكن المميزات المتقدمة Advanced Features تختلف.
أيضا، يمكن للغة التجميع أن تكون منقولة Portable عبر عدة أنظمة تشغيل، وعلى وحدة معالجة مركزية CPU واحدة. فاصطلاحات Conventions استدعاء الوظائف لا تختلف كثيرا بين أنظمة التشغيل المختلفة وأحيانا لا تختلف على  الإطلاق، وببعض الحرص Care، يمكن الحصول على "نقالية" Portability في لغة التجميع، وعادة يتم ذلك عبر الربط مع مكتبة سي C والتي لا تتغير بين نظم التشغيل.
وعلى سبيل المثال، العديد من الأشياء داخل مكتبة لغة السي libc تعتمد على "ما قبل المعالجة" Preprocessor لتقوم بأشياء مرتبطة بنظام التشغيل OS-Specific، واشياء مرتبطة بلغة السي C-Specific، وتقوم بعمل ذلك للبرنامج قبل أن تبدأ في الترجمة Compiling.وفي واقع الأمر، فإن بعض الوظائف والرموز لا يمكن ضمان وجودها خارج الـ Preprocessor.الأسوأ من ذلك، أن حجم وترتيب البنيات Structs، فضلا عن حجم بعض أنواع من تعريف الأنواع typedefs مثل off_t، لا يوجد تعريف مثل هذه الاشياء في لغة التجميع -بدون مساعدة من ملف خارجي لتحديد هذه القيم Configure Script-، وتختلف حتى بين الإصدارات المختلفة من لينكس Linux، مما يجعل من المستحيل أن يتم استدعاء وظائف من مكتبة السي libc بشكل نقال Portable، غير تلك التي تتعامل بشكل بسيط مع القيم الصحيحة Integers والمؤشرات Pointers كمعاملات.ولمعالجة هذه المسألة، يقوم مشروع FASMLIB (مكتبة للمجمع FASM) بتوفير مكتبة نقالة للمجمع تعمل على منصات Win32 ولينكس Linux، لكنها ليست كاملة بشكل كافي حتى الآن.
بعض لغات برمجة الحاسوب عالية المستوى، مثل لغة السي C ولغة "بورلاند باسكال" Borland Pascal، تدعم التجميع الداخلي Inline Assembly حيث يمكن دمج فقرات صغيرة نسبيا من كود التجميع داخل الكود المكتوب باللغة عالية المستوى.وغالبا ما تحتوي لغات البرمجة Forth على مجمعاً يستخدم في كلمات CODE Words.
ويستخدم العديد من الأشخاص نظم "المضاهاة" Emulator من أجل كشف وتصحيح Debug أخطاء البرامج المكتوبة بلغة التجميع.
مثال يقوم بعرض كود المصدر الخاص بلغة التجميع

مثال على مجموعة مختارة من التعليمات (من أجل كمبيوتر افتراضي Virtual Computer)
مع العناوين المقابلة في الذاكرة حيث يتم وضع كل تعليمة.هذه العناوين ليست ثابتة Static، انظر إدارة الذاكرة.
ويقوم بمصاحبة كل تعليمة مولدة (عبر المجمع) الكود النهائي Object Code والذي يتوائم مع هندسة الكمبويتر الافتراضي Virtual Computer's Architecture.
وانظر أيضا
مترجم Compiler
مفكك Disassembler
مجموعة تعليمات
كمبيوتر الرجل الصغيرLittle Man Computer- عبارة عن نموذج لحاسب تعليمي مزود بلغة تجميع ذات قاعدة عشرية Base-10
مجمع مايكرو Microassembler
لغة تجميع مكتوبة Typed
المراجع

لمزيد من المطالعة
"كتاب مجتمع التجميع ASM"، كتاب متوفر على الويب ويحتوي معلومات مفيدة عن الـ ASM، بجانب دروس تعليمية، وأمثلة للكود. By ASM Community
جوناثان بارتليت: البرمجة من الألف إلى الياء.دار بارتليت للنشر, 2994. ISBN 0-9752838-4-7
ومتوافر أيضا على شبكة الإنترنت في صيغة PDF
روبرت بريتون: البرمجة باستخدام لغة التجميع MIPS.دار برنتيس هول للنشر، 2003. ISBN 0-13-142044-5
بول كارتر:لغة التجميع للحاسب الشخصي PC.كتاب مجاني، 2001.

جيف دانتيمان: لغة التجميع خطوة بخطوة.دار وايلي للنشر، 2000. ISBN 0-471-37523-3
راندال هايد: فن لغة التجميع.دار "نو سكراتش" للطباعة، 2003. ISBN 1-886411-97-2
تتوافر مسودات الكتاب على شبكة الإنترنت في صيغ PDF وHTML
بيتر نورتون، جون سوتشا، كتاب بيتر نورتون حول لغة التجميع لأجهزة الحاسب الشخصي من نوع IBM، دار برادي للكتب، نيويورك: 1986.
مايكل سينجر، PDP-11.البرمجة باستخدام لغة المجمع، وتنظيم الآلة Machine Organization، دار جون ويلي وأبناؤه للنشر: نيويورك: 1980.
دومينيك سويتمان: انظر لـ MIPS وهو يعمل.مورجان كوفان للنشر, 1999.ISBN 1-55860-410-3
جون والدورن: مقدمة للبرمجة باستخدام لغة التجميع RISC.دار أديسون ويسلي للنشر، 1998.  ISBN 0-201-39828-1
وصلات خارجية

كتاب الفلسفة "فن لغة التجميع" لراندال هايد، متوفر بصيغتي PDF وHTML
لغة الآلة للمبتدئين
مقدمة للغة التجميع
مجتمع الـ ASM، مصدر معلومات عن البرمجة باستخدام لغة التجميع ويحتوي كتابا للـ ASM
جدول الكود الخاص بلغة التجميع الخاصة بمعالجات Intel 80x86 (ورقة مرجعية)
البرمجة باستخدام لغة التجميع الخاصة بيونيكس
القواعد الرئيسية لتشغيل هندسة IMB z، دليل الحواسب الكبيرة لـ IBM الخاص بلغة الآلة وبالعمليات الداخلية.
مجمع IBM عالي المستوى، دلائل IBM للغة التجميع الخاصة بالحواسيب الكبيرة.
PPR: تعليم لغة التجميع
مقدمة لكتابة تطبيقات من نوع 32-bit باستخدام لغة التجميع x86
أمثلة على البرمجة باستخدام لغة التجميع
كتابة تطبيقات لويندوز باستخدام لغة التجميع
معلومات حول برمجة التجميع على لينكس
المرجع الخاص بمجموعة التعليمات للمعالج x86
دروس تعليمية للغة التجميع Iczelion's Win32
نصائح لتحسين كود التجميع، مارك لارسون
دليل NASM
كتابة الكود بلغة التجميع 8086, ف. آيه. سميت
برمجيات
مينوت-أو-إس MenuetOS، نظام تشغيل تم كتابته كلية باستخدام لغة التجميع 82/64 بت.
مجمع SB، يعمل مع معظم المعالجات/ المتحكمات من نوع 8 بت.
مكتبة GNU Lighting، وهي مكتبة تقوم بتوليد كود بلغة التجميع يعمل في وقت التشغيل Run-Time، ومفيدة جدا للمترجمات من نوع Just-In-Time.
مجمع نيت-وايد Netwide
جو-اسم GoAsm، مكون مجاني من أدوات Go: يدعم برمجة ويندوز من نوع 32 بت و64 بت


تصنيف:لغات التجميع
تصنيف:لغات تجميع