الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

بناء Assemblers

بدأه MohamedIBrahim في 31 مايو 2011 · 6 رد · 1,449 مشاهدة · في هندسة البرمجيات
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمه الله وبركاته

اهلا بالشباب وكل اعضاء المنتدى الكرام حبيت اليوم أكتب لكم عن موضوع شيق وممتع للغاية وسأوضح

فيه ان شاء الله فكرة من افكار عمل Assembler طبعا هناك فرق ما بين

Assembler

تعريفه :-

الأسمبلر هو اسم الmodule الذي يقبل مدخل(input) من لغة الAssembly و يُنتج (output) مُخرج من لغة الإلة Machine Code و في العادة يكون تصميم الأسمبلر بسيط فهو مجرد Line by Line Translation أي مترجم سطري و هذا لطبيعة الAssembly البسيطة فهو يقوم بعمل Recognition للأوامر (mnemonics) و تحويلها الى الmachine code المناظر لها متبوعاً بالقيم التي تليه

بالطبع الAssemblers الأحدث أكثر تعقيداً و لكن مازالت الفكرة الأساسية واحدة...

وكان تطوير لغات المجمّع أحد أول الاختراعات الهامة في تاريخ اللغات البرمجية. وقد كانت هذه اللغات أول أداة ساعدت المبرمجين على عناء التعامل مع الأصفار والواحدات، ومكنتهم من استخدام تسميات برمجية ذات دلالة خاصة بالتعليمات والإجراءات. وكان أول مجمّع عبارة عن نظام يقوم بتمثيل تعليمات لغة الآلة برموز بسيطة Mnemonic يسهل تذكرها

كانت البرامج المكتوبة بلغة المجمّع أكثر قابلية للقراءة من الشيفرة الثنائية، على أنه كان ينبغي ترجمتها إلى لغة الآلة باستخدام برنامج حاسوبي خاص يدعى بالمجمّع.

يقبل المجمّع برنامجاً مكتوباً بلغته ويعتبرها معطيات، ويحول رموز Opcode إلى مكافئاتها الرقمية، ويربط العناوين الرمزية بمواضع الذاكرة، ومن ثم يقوم بتوليد برنامج بلغة الآلة. يدعى برنامج لغة المجمّع بالبرنامج المصدري أو Source Program، يدعى البرنامج النهائي المكتوب بلغة الآلة بالشيفرة العنصر أو Object Program.

وبما أن تعليمة واحدة من تعليمات لغة المجمّع تولد تعليمة واحدة أو عنصر معطيات وحيد، لذا فقد عرفت لغة المجمّع كلغة برمجية من مستوى "نظير-لنظير". وبنتيجة ذلك، تستند المجمعّات على الآلة أو الجهاز، ويتم توليد هذه الشيفرات الخاصة بنوع محدد من الحواسب

ولليوم، لاتزال عملية البرمجة بلغة المجمّع هي أساس بعض المهام البرمجية. فمثلا، يمكنكم زيادة سرعة البرنامج بالدخول إلى السجلات الداخلية مباشرة، عوضاً عن الدخول إلى مواضع الذاكرة التي تعتبر أبطأ. هذا، وإن معظم اللغات البرمجية عالية المستوى لاتتيح للمبرمج بهذا المستوى من التحكم

ميزات لغة المجمّع:

- تعطى جميع العمليات أسماء ذات دلالة أو رمز Opcode يسهل تذكره، مثل ADD؛

- يتم استخدام تسيمات رمزية لكافة المعطيات وعناوين الذاكرة، الأمر الذي يسهل على المبرمج مهمة تخصيص أماكن التخزين في الذاكرة؛

- تخفض من نسبة الأخطاء الطباعية من خلال استخدام العناوين الرمزية؛

- من الأسهل قراءة وفهم البرنامج المكتوب بلغة المجمّع.

مساوئ لغة المجمّع:

- لا بد من كتابة سطر من لغة الآلة لكل تعليمة في الآلة، وبالتالي تتطلب البرامج الكبيرة آلافاً من الأسطر المكتوبة بلغة المجمّع؛

- يطلب من المبرمجين معرفة الخصائص الوظيفية الداخلية للحاسوب؛

- يتوجب ترجمة البرنامج المكتوب بلغة التجميع باستخدام برنامج خاص يدعى المجمع (Assembler)، وذلك قبيل التنفيذ.

compiler

الCompiler هو اسم الmodule الذي يقبل input من لغة High Level مثل الC و يعطي output من الObject Code المناظر له..

يتميز المترجم عن المجمّع بحقيقة وحيدة، وهي أن كل تعليمة من تعليمات الدخل لا تكافئ تعليمة واحدة من تعليمات لغة الآلة، أو سلسلة متكاملة من التعليمات. هذا، ويمكن للمترجم دعم عدة ميزات، كالتحديد التلقائي لمواضع المتحولات، والتعابير الحسابية، وبنى التحكم، كحلقات FOR و WHILE، ومجالات رؤية المتحولات، وعمليات الدخل والخرج، والتوابع ذات الترتيب الأعلى ومحمولية التشفير المصدري

ويتم الإعلان عن الخطأ إذا تم اكتشافه أثناء الترجمة، أما إذا كانت الأخطاء خطيرة، فقد يتوقف المترجم عن تتمة عملية الترجمة كلياً. إضافة، ينبغي على المترجم أن يتمكن من الدخول إلى مكتبة الإجرائيات أو البرامج الجزئية، حيث تتضمن هذه المكتبة العديد من البرامج والإجرائيات اللازمة لتنفيذ العمليات الحسابية، وعمليات الدخل والخرج، والتخزين الوقائي لنقاط تحويل المعطيات. وحيثما أشار البرنامج المصدري لإحدى هذه الإجرائيات، أو احتاج لتنفيذ عملية محددة، يقوم المترجم بالتأكد من إضافة الإجرائية المكتوبة بلغة الآلة إلى التشفير العنصر

وفي حالة تم تعديل البرنامج المصدري لاحقاً، فينبغي إعادة كامل عملية الترجمة وهذا الامر مرهق احيانا

Interpreter

الinterpreter هو اسم الmodule الذي يقوم بعملية الترجمة للسطر ثم ينتظر تنفيذه ثم ينتقل للسطر الأخر و هكذا و هو يشبه الى حد ما الCompiler و لكنه في أغلب الأحيان لا يمكن ان تُنتج منه Executable File أي أنه يجب أن يقوم الinterpreter بعمل الترجمة كل مرة لتشغيل البرنامج كما أن مهمته تزداد تعقيداً في وجود الLoops و الConditions و لأنه يجب عليه أن يترجم الloop كلها ثم يحتفظ بالكود الخاص بها في الذاكرة حتى يكررها ثم ينتقل بعد هذا الى مابعدها...

وبدون الخروج عن الهدف الاصلى من الدرس وهو ان اوضح احد افكار تصميم الاسمبلر (Assembler)

واحدة من الوسائل التى تستخدم فى صناعة الاسمبلر هى كتابة الSyntax للغة الاسمبلى ( assembly language) بالBNF ومن ثم زيادته بالحاق كل قاعدة باسم الدالة (function ) ليتم منادتها عندما تتفق القاعدة

وعلى سبيل المثال سوف نطلق على على زيادة الSyntax اسم +BNF

عندما نمتلك محرك BNF الاساسى يعمل فاننا نستطيع بناء الاسمبلر له وفى العادة تسمى ( Compiler-Compiler) >>>(لكن هذا اسمبلر وليس مترجم )

نستطيع كتابة BNF لنفسه وفى مثالنا +BNF نقوم بادخاله على اساس انه Input ألى الEngine

وتخرج مجموعة من جداول التحكم (control tables) سيكون المحرك على هذا النمط وهو سوف يكون قادرا على قراءة اى شئ فى +BNF (على سبيل المثال لغة الاسمبلى المعروفة)

بالاضافة الى محرك BNF فنحن نحتاج الى symbol table وايضا دوال back-end code generation

تستطيع عمل كل هذا بدون tokeniser بتعريف Token على BNF , والسماح للمحرك الرئيسى بعمل هذا العمل وهذا سهل لكنه يعيبه البطئ

وهذه بعض الامثلة غير الكاملة للتوضيح لكنها ينبغى ان يقوم بتوضيح الامور التى اريد ايصالها

قطعة من BNF + ملف بناء Syntax :-

* rule        elements                      semantic function
file        = {oneline} [eof]           .
oneline     = line ending               .   NextLine
*-----------------------------------------------
* Basic elements
eof         = #26                       .
eol         = {ws} [comment] #10        .
ws          = wsc {wsc}                 .
wsc         = " "                       |
               #9                        .
digit       = ("0".."9")                .
uphex       = ("A".."F")                .
lowhex      = ("a".."f")                .
upper       = ("A".."Z")                .
lower       = ("a".."z")                .
hexchar     = digit                     |   HexValueDigit
               uphex                     |   HexValueUpper
               lowhex                    .   HexValueLower
letter      = upper                     |
               lower                     .
symch       = letter                    |
               digit                     |
               "_"                       .

Top-level function of the BNF+ engine:

// Syntax "engine": the core of the system
#define SP        current.syntab[current.synptr]
#define GETCHR    {currch = getchr(&current);}
#define NEXTCH    {lastch = currch; current.fileptr++; \
   GETCHR; if(currch=='\n') current.linum++;}
#define GOTOCH(x) {current.fileptr = x; GETCHR}
#define EXIT      {if(init.filename) fclose(init.input); \
   return(current);}

state engine(state init)
{
     state current;          // Local copy (we may want to back-up)
     state temp;             // Workspace for recursive calls
     WORD rule;
     char error[100];
     char currch;

     init.depth++;

     if(init.filename)       // Open new file...
     {
         if(!(init.input = fopen(init.filename, "rb")))
         {
             sprintf(error,"Fatal: cannot open file %s\n", init.filename);
             fatal(error);
         }

         init.fileptr  = 0;          // Start at BOF
         init.linum    = 1;
         getchr(NULL);               // Force a re-read
     }

     current = init;
     current.filename = NULL;        // File dealt with
     GETCHR;

     do
     {
         rule = SP;
         currstate = &current;       // Expose it for logging

#if LOGSTATE
         {
             static int ctr = 0;
             char zz[8];
             if((currch >= 0x20) && (currch <= 0x7e))
                 sprintf(zz,"<%c> ",currch);
             else
                 sprintf(zz,"0x%02x", currch);
             fprintf(logfile,"%5d %3d%6d [%4d]  %s [%4d] %c\n",ctr++, 
init.depth, rule,current.synptr, zz, current.fileptr, (current.match) ? 
'T' : 'F');
             fflush(logfile);
         }
#endif

         if(rule < 0)                // SUB RULE
         {
             if(current.match)
             {
                 temp = current;
                 temp.synptr = -rule;            // Rule address
                 temp = engine(temp);
                 current.match  &= temp.match;
                 if(temp.match)
                     GOTOCH(temp.fileptr);
             }
         }
         else
         {
             if(rule < 200)          // LITERAL CHAR
             {
                 current.match &= ((char)rule == currch);
                 if(current.match)
                     NEXTCH
             }
             else
             switch(rule)
             {
             case 202:               // '|'  ALTERNATE RULE
                 if(!current.match)
                 {                           // Last test failed: 
back-up & try next
                     current.match = init.match;
                     current.fileptr = init.fileptr;
                     current.synptr++;       // To start of new rule
                     break;
                 }
                 // Else, fall through (rule succeeded)
             case 201:               // '.'  END OF RULE
                 current.synptr++;           // Point at semantic
                 if(current.match)
                 {
#if LOGSEMANTIC
                     char zz[8];
                     if((lastch >= 0x20) && (lastch <= 0x7e))
                         sprintf(zz,"<%c> ",lastch);
                     else
                         sprintf(zz,"0x%02x", lastch);

                     if(SP)
                         fprintf(logfile,"   Semantic[%4d] %s\n",SP,zz);
                     fflush(logfile);
#endif
                     semantics[SP]();        // Semantic function (zero 
is valid)
                 }
                 EXIT;

             case 203:               // '{'
             case 204:               // '['
                 temp = current;
                 temp.synptr++;
                 temp = engine(temp);
                 if(temp.match)              // If it worked, swallow 
the chars.
                     GOTOCH(temp.fileptr);
                 if(current.syntab[temp.synptr] != 2+SP)
                 {
                     sprintf(error,"Fatal: bracket imbalance at 
%d:%d\n", temp.synptr, current.synptr);
                     fatal(error);
                 }

                 if(temp.match && (current.syntab[temp.synptr] == 205))
                     continue;               // {...} repeats indefinitely
                 else
                     current.synptr = temp.synptr;
                 break;

             case 205:               // '}'
             case 206:               // ']'
                 EXIT;

             case 207:               // RANGE
                 current.match &= ((currch >= 
(char)current.syntab[current.synptr+1]) && (currch <= 
(char)current.syntab[current.synptr+2]));
                 current.synptr += 2;
                 if(current.match)
                     NEXTCH;
                 break;

             case 208:               // '@' - include file
                 temp = current;
                 temp.filename = Identifier;
                 temp.fileptr  = 0;          // Start at BOF of inner file
                 current.synptr++;           // Point to nested rule
                 temp.synptr   = -SP;
                 temp = engine(temp);        // Run the nested file
                 current.match &= temp.match;

             default:
                 {
                     sprintf(error,"Fatal: unrecognised syntax code at 
[%d] = %d\n", current.synptr, rule);
                     fatal(error);
                 }
             }
         }

         if(!current.match)          // If this rule failed, back-up
             GOTOCH(init.fileptr)

         do
         {
             current.synptr++;       // Next syntax item (skip if tests 
have failed)
         } while(!(current.match || (SP > 200)));

     } while(1);                     // End the DO loop
}

الدرس بسيط والفكرة ابسط وان شاء الله سأحاول الا يكون الدرس الوحيد وسوف اتبعه بمقالات جديدة عندما اجد الوقت

طبعا فكرة الدرس بسيطة جدا وهذا المجال صناعة الاسمبلرات كبير جدا ومتشعب ويحتاج دراسة

وانا انصح لمن يريد الاستزادة بكتاب Art Of Computer Programming

طبعا انا منتظر اى نقد او اقتراحات او اخطاء تصحيحها من الخبراء والاخوة الافاضل ومنكم نستفيد

وتحياتى للجميع

تم تعديل هذه المشاركة بواسطة MohamedIBrahim في 1 يونيو 2011 في 10:56

3

GoodBye

#2

لدي اعتراض على ما ذكر هنا:

اقتباس

- يتوجب ترجمة البرنامج المكتوب بلغة المجمّع باستخدام برنامج خاص يدعى المترجم، وذلك قبيل التنفيذ.

إن كانت هذه من المساوئ فحتى الـ compilers تشترك بها، لم هي من "مساوئ" لغة التجميع؟

1

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#3
Xacker كتب:

لدي اعتراض على ما ذكر هنا:

إن كانت هذه من المساوئ فحتى الـ compilers تشترك بها، لم هي من "مساوئ" لغة التجميع؟

اهلا بك اخى الحبيب

لم اقل انها سيئة تحسب فقط للاسمبلرات ولم اذكر مساؤئ compilers لاننى كنت اركز فى الدرس على assemblers

بالاضافة الى اننى اخطئت عندما كتبت الجملة التى اعترضت عليها وذكرت ان البرنامج هو المترجم وليس الاسمبلر :)

شكرا على التنبيه

GoodBye

#4

استكمالا لبعض النقاط

تطوير المجمعات :-

فى لغات الحاسب السابقة كانت كل لغات التجميع سابقا تمتلك Syntax سهل نسبيا

ما هى فوائد بناء مجمع ؟

1-كتابة مجمع ستعطى المبرمج تقدير جيدا لترميز التعليمات

2- كتابة مجمع سوف تمكن المبرمج من اضافة ما يريد من خصائص الى المجمع

3-كتابة مجمع تسمح للكاتب بتصميم Syntax للغة التجميع كما يفضل

4-كتابة مجمع هو مشروع متوسط المستوى جيدا للبداية للمبرمجين المتوسطين لكتابة المجمعات والتعامل معها والسماح لهم بصقل مهارات البرمجة الخاصة بهم على مشروع عملى

ما هى عيوب بناء مجمع ؟

لسوء الحظ هناك عيوب عديدة لكتابة مجمع ومنها ما يلى

تصميم مجمع صغير الجودة ليست مهمة صعبة لكن كتابة المجمعات التجارية ذات جودة عالية مع وضع خصائص احترافية هو مشروع ضخم ويحتاج للكثير من المجهود والخبرة وايضا المهارة واحيانا يحتاج تمويل وتكون مستحيلة اذا لم يكن المبرمج او المبرمجون الذين يعملون على المشروع لديهم المهارة الكافية لانجاز المشروع

1- تصميم مجمع حديث هذه الايام يحتاج معرفة جيدة بالمترجمات وللاسف فان تقريبا معظم المبرمجين المتوسطين لا يمتلكون هذه المعرفة

2- تصميم مجمع سريع وهو مجمع يريد الاخرون دائما استخدامه اثناء البرمجة بلغة التجميع او اى استخدام اخر فان هذا الامر يتطلب معرفة عميقة لهياكل البيانات والخوارزميات والامر سهل اذا ما كنت تقوم بكتابة مجمع صغير والذى يطلق عليه عادة "Toy Assembler " والذى يكون يعمل بشكل جيد كمشروع صغير يمكن الانتهاء منه سريعا وبسهولة لكن الاكثر صعوبة هو تصميم مجمع ذو نظام عالى الامكانيات وذو كفاءة فى الاداء لانه ليس كالمشاريع الصغيرة

3- أثناء كتابة الكود لعملية باستخدام تعليمات الجهاز الفردية هو امر ممتع وشيق ومثير للاهتمام والمجمع ذو الجودة والامكانيات العالية الحديث يتطلب الكثير من التعليمات البرمجة الاخرى للتعامل مع declarations و انواع البيانات و وحدات الماكرو وغيرها من الميزات والخصائص المتقدمة وهذه الخصائص ليست بالسهولة التامة او بالوضوح التام لكى يتم تطويرها

GoodBye

#5

لم أرى هذا الموضوع إلا الأن، مجهود طيب أخي محمد.

توجد لدي بعض التنقيحات على المحتوي إن سمحت لي:

اقتباس
يقبل المجمّع برنامجاً مكتوباً بلغته ويعتبرها معطيات، ويحول رموز Opcode إلى مكافئاتها الرقمية،

الصحيح: يقبل المجمّع برنامجاً مكتوباً بلغته ويعتبرها معطيات، ويحول رموز Instruction إلى مكافئاتها الرقمية و تسمي Opcode و هي لإختصار لـ operation code

اقتباس
- لا بد من كتابة سطر من لغة الآلة لكل تعليمة في الآلة، وبالتالي تتطلب البرامج الكبيرة آلافاً من الأسطر المكتوبة بلغة المجمّع؛

و لهذا وجدت الدوال التى تجعلك تمنع تكرار نفس الكود و بالتالي تستطيع تقسيم البرامج الضخمه إلى قطع صغيره سهله المراجعه و التصحيح، مشكلة حجم البرامج موجوده ايضا بالغات العاليه المستوى مثل السي و السي++ و الجافا و ليست حكرا على الأسمبلي.

اقتباس
- يطلب من المبرمجين معرفة الخصائص الوظيفية الداخلية للحاسوب؛

تعتمد على طبيعة البرنامج الذى تقوم بصناعته، فبداخل لغة السي او الجافا انت تستخدم الـ stack و تعرف ما هو، نفس الكلام فى الأسمبلي و لكن كيفية التعامل مع الـ stack هي التى تختلف من لغه لأخرى. معرفة الأنظمه الداخليه للحاسب يحتاجها فقط من سيتعامل مع الـ kernel او مبرمجي انظمة التشغيل حيث هي من الأساسيات لهم و لغيرهم هي امتياز تساعدهم على بناء تطبيقات اسرع ليس إلا.

اقتباس
- يتوجب ترجمة البرنامج المكتوب بلغة التجميع باستخدام برنامج خاص يدعى المجمع (Assembler)، وذلك قبيل التنفيذ.

كود الأسمبلي عند تمريره للأسمبلر يتم انتاج الـ object code و هو بطبيعته غير قابل للتنفيذ، هنا ياتي دور ال Linker لتجميع الـ object code معا و إتمام external linkage و من ثم انتاج الملف التنفيذي ليتم تنفيذه من قبل نظام التشغيل.

إستخدام الكلمه "خاص" مع الكلمه "برنامج" فى الجزء "باستخدام برنامج خاص يدعى المجمع" توحى بان الأسمبلر هو حاله خاصه من المترجمات و الذى عادة لا يتم استخدامه و هذا غير صحيح حيث أن أغلب المترجمات تقوم بتوليد كود أسمبلي و ليس object code و لهذا فإن الأسمبلر هو من اهم اجزاء ألتى تكون المترجم.

لغة الأسمبلي - من وجهة نظرى - لا عيب لها إلا السمعه التى حصلت عليها من المبرمجين الذى لا يعرفوها.

اقتباس
الCompiler هو اسم الmodule الذي يقبل input من لغة High Level مثل الC و يعطي output من الObject Code المناظر له..

الCompiler هو اسم الmodule الذي يقبل input من لغة High Level مثل الC و يعطي output من الAssembly Code المناظر له.

بالنسبه للـ Interpreter يوجد نوع أخر و هو syntax checker مثل الموجود بالمحررات و هو يقوم بالتحقق من ان هيكل الكود مطابق لقواعد اللغه و يميزه انه على خلاف المترجم فهو لا ينتج كود و انما مهمته تتلخص فى بناء parse tree للكود الموجود و فى حالت وجود اخطاء يقوم بإظهارها مباشرة.

**************************

جدير بالذكر أن الأسمبلر التجاريه يتم تضمينها بإستخدام Hard Code و ليس Table Driven بإستخدام ادوات مثل Flex و ذلك لبطئها.

فعليا يتم برمجة المترجم أو الأسمبلر (الـ Lexer و الـ parser) بإستخدام اداه مثل الـ Flex و ذلك لسهولة التعديل على قواعد اللغه و لسهولة تنقيح المترجم أو الأسمبلر و بعد الإنتهاء منه يتم إعادة كتابة الجزء المولد إلى Hard Code و ذلك لتحسين و تسريع الـ Lexer و الـ Parser.

و الله ولي التوفيق

تم تعديل هذه المشاركة بواسطة محمد علاء الدين في 2 يونيو 2011 في 14:38

مدونتي: C++ Tips and Tricks

#6
محمد علاء الدين كتب:

لم أرى هذا الموضوع إلا الأن، مجهود طيب أخي محمد.

اهلا وسهلا بك ومنور الموضوع وافدة شخصية لى وللجميع كعادتك

محمد علاء الدين كتب:

توجد لدي بعض التنقيحات على المحتوي إن سمحت لي:

بالطبع اخى الحبيب

محمد علاء الدين كتب:

الصحيح: يقبل المجمّع برنامجاً مكتوباً بلغته ويعتبرها معطيات، ويحول رموز Instruction إلى مكافئاتها الرقمية و تسمي Opcode و هي لإختصار لـ operation code

و لهذا وجدت الدوال التى تجعلك تمنع تكرار نفس الكود و بالتالي تستطيع تقسيم البرامج الضخمه إلى قطع صغيره سهله المراجعه و التصحيح، مشكلة حجم البرامج موجوده ايضا بالغات العاليه المستوى مثل السي و السي++ و الجافا و ليست حكرا على الأسمبلي.

اخى محمد من الواضح اننى لم اذكر شئ عن اللغات العالية المستوى وعيوبها اعلم ان هناك عيوب مشتركة بينها وبين الاسمبلى وكذلك ليس هذا هو العيب الوحيد المشترك

محمد علاء الدين كتب:

تعتمد على طبيعة البرنامج الذى تقوم بصناعته، فبداخل لغة السي او الجافا انت تستخدم الـ stack و تعرف ما هو، نفس الكلام فى الأسمبلي و لكن كيفية التعامل مع الـ stack هي التى تختلف من لغه لأخرى. معرفة الأنظمه الداخليه للحاسب يحتاجها فقط من سيتعامل مع الـ kernel او مبرمجي انظمة التشغيل حيث هي من الأساسيات لهم و لغيرهم هي امتياز تساعدهم على بناء تطبيقات اسرع ليس إلا.

كلام صحيح والامر يعتمد على كيفية فهم التعليمات من مجال لاخر ومن شخص لاخر مع الملاحظة ان درجة الفهم قد تختلف ما بين مستخدمى النوع الواحد فمثلا قد يختلف احد المبرمجين مع الاخر حول احد المفاهيم فى اللغات العالية مثل الC

محمد علاء الدين كتب:

كود الأسمبلي عند تمريره للأسمبلر يتم انتاج الـ object code و هو بطبيعته غير قابل للتنفيذ، هنا ياتي دور ال Linker لتجميع الـ object code معا و إتمام external linkage و من ثم انتاج الملف التنفيذي ليتم تنفيذه من قبل نظام التشغيل.

يتم دمجه عادة مع Linker ويكون الاسمبلر جاهز من كافة خطوات بناء التطبيق

محمد علاء الدين كتب:

إستخدام الكلمه "خاص" مع الكلمه "برنامج" فى الجزء "باستخدام برنامج خاص يدعى المجمع" توحى بان الأسمبلر هو حاله خاصه من المترجمات و الذى عادة لا يتم استخدامه و هذا غير صحيح حيث أن أغلب المترجمات تقوم بتوليد كود أسمبلي و ليس object code و لهذا فإن الأسمبلر هو من اهم اجزاء ألتى تكون المترجم.

كما قلت فان اغلب المترجمات تقوم بالتحويل الى كود اسمبلى لذا فان الاسمبلر هو من اهم اجزاء معظم المترجمات وليس الامر عاما على كل المترجمات

محمد علاء الدين كتب:

لغة الأسمبلي - من وجهة نظرى - لا عيب لها إلا السمعه التى حصلت عليها من المبرمجين الذى لا يعرفوها.

وليس كذلك فقط بل هناك اسباب اخرى مثل سمعتها السيئة حيث يعتقد البعض بأنها لغة للاختراق للاجهزة والبرامج ليس اكثر وهذا فهم خاطئ بالطبع

وكذلك اعتقاد البعض بصعوتها البالغة واقتصار التطبيقات والبرامج على مستوانا العام على تطبيقات التى تستخدم برامج عالية المستوى مثل جافا وسى شارب ....الخ

محمد علاء الدين كتب:

بالنسبه للـ Interpreter يوجد نوع أخر و هو syntax checker مثل الموجود بالمحررات و هو يقوم بالتحقق من ان هيكل الكود مطابق لقواعد اللغه و يميزه انه على خلاف المترجم فهو لا ينتج كود و انما مهمته تتلخص فى بناء parse tree للكود الموجود و فى حالت وجود اخطاء يقوم بإظهارها مباشرة.

اذا سمحت هل هذا يتم بنفس الطريقة ام انه يتلخص فى front وعمل مصحح للمترجم فقط

**************************

محمد علاء الدين كتب:

فعليا يتم برمجة المترجم أو الأسمبلر (الـ Lexer و الـ parser) بإستخدام اداه مثل الـ Flex و ذلك لسهولة التعديل على قواعد اللغه و لسهولة تنقيح المترجم أو الأسمبلر و بعد الإنتهاء منه يتم إعادة كتابة الجزء المولد إلى Hard Code و ذلك لتحسين و تسريع الـ Lexer و الـ Parser.

الامر يتعلق بمدى مهارة وخبرة من يقوم بتصميم الاسمبلر حيث ان عامل السرعة والجودة العالية يعتمد ليس فقط على ما الذى يستخدم فى بناءه بل ايضا ومن يقوم باستعمال الادوات التى يبنى بيها

محمد علاء الدين كتب:

و الله ولي التوفيق

نورتنى بتعليقك المفيد يا محمد واتمنى لك دوام الصحة والعافية

GoodBye

مواضيع مشابهة