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

Virtual Machine in C للمتوسطين والمحترفين

مغلق
بدأه mossa في 3 نوفمبر 2004 · 4 رد · 1,099 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

Virtual Machines

الآلات الإفتراضية

معلومة اليوم/

إذا لم تستطع صنع آلة فإنه بوسعك أن تحاكيها.

لتكن العبارة السابقة هي محور هذا الموضوع.

ما أطمح إلية أن يكون هذا الموضوع بمثابة عصا سحرية تفتح مجالك البرمجي للإبداع...

لماذا Virtual Machines؟

هل تعرف Java Virtual Machine (JVM) ؟

عبارة عن برنامج يقوم بعمل واجهة بينك وبين الحاسب بحيث يمكنك من التعامل معه.

أكثر من ذلك يمكنك من التعامل مع أكثر من نظام تشغيل.

وأكثر من ذلك يمكنك من التعامل مع أكثر من آلة.

بينما لغة Java هي نفسها لم تتغير بحيث أن برنامجك الواحد يمكنه العمل على أغلب منصات العمل.

متى تحتاج كمبرمج VM؟

عن نفسي : درست مقرر Compiler Design وكتبت لغة برمجة بسيطة جداً حيث تأخذ النص الأصلي وتحوله إلى لغة قريبة من لغة التجميع وانتهى المقرر.

والمشكلة ظهرت عندما أردت أن أنفذ البرنامج (كيف؟) كيف أحول الملف إلى صيغة exe.

وبينما أنا أبحث عثرت على VM.

- وأيضا كنت أتتبع كود لـ محرك SQL ووجده هو أيضا يستخدم VM

كيف أكتب VM خاص بي؟

لست أبالغ أن برمجة VM هي من أسهل مجالات البرمجة لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن

لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن لكن

الأهم هو فهم طبيعة عمل الآلة .

لحسن الحض أن هناك آلات سهلة يمكن البدء بها وستكون مفيدة بإذن الله.

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

مبدئياً/ سنأخذ آلة المكدس stack machine وتحتوي على:

معالج processor

ذاكرة memory

تعليمة instuction

بنية المعالج ستكون كالتالي

struct processor{
instruction IR, /* instruction reg */
int PC, /* Program Counter */
int SP  /* Stack Pointer */
} CPU;

أما التعليمة فتمثل كالتالي

struct instruction

{
	int opcode; /* قيمة التعليمة*/
	int arg;       /* المعامل */
};

أما الذاكرة فهي عبارة عن مصفوفتين

int stack[1024]; /* تستخدم لأجل تنفيذ العمليات */
instruction code[1024]; /* لتخزين الكود */

أما إجرائية عمل الآلة فهي كالتالي:

BEGIN
    code := fetch_from_file(); (* تحويل التعليمات من نصوص إلى أكواد *)
    CPU.PC := 0;  (* عنوان أول تعليمة *)
    LOOP
      CPU.IR := code[CPU.PC]; (* جلب التعليمة من الذاكرة *)
      CPU.PC++;                (* زيادة مؤشر العنوان للتالي *)
      Execute(CPU.IR);         (* تنفيذ التعليمة *)
    END
END.

بعد اللمحة البسيطة عن عمل الألة.

لنذهب إلى البرمجة/

هناك مايسمى تمثيل داخلي (أي داخل البرنامج)

تمثل كل تعليمة برقم معبن بحيث يسهل التعامل معها.

وهناك تمثيل خارجي (خارج البرنامج)

تمثل كل تعليمة بنص.

تتم عملية جلب التعليمات من الملف ونقلها إلى مصفوفة الأكواد.

ثم يبداء العمل داخل التكرار الموضح

سوف أكتب مجوعة من التعليمات وتنفيذها

read إقرأ من سطر الأوامر

write أكتب إلى الشاشة

add إجمع

sub إطرح

mul اضرب

div إقسم

وتتم كالتالي :

stack[CPU.SP-1] = stack[CPU.SP-1] [+-/*] stack[CPU.SP--];

eq مقارنة

stack[CPU.SP-1] =  stack[CPU.SP-1] == stack[CPU.SP--] ? 1 : 0;

lt مقارنة

stack[CPU.SP-1] =  stack[CPU.SP-1] < stack[CPU.SP--] ? 1 : 0;

gtمقارنة

stack[CPU.SP-1] =  stack[CPU.SP-1] > stack[CPU.SP--] ? 1 : 0;

ld حمل إلى stack

stack[++CPU.SP] = CPU.IR.arg;

st خزن في stack

stack[CPU.IR.arg] = stack[CPU.SP--];

goto إنقل تنفيذ البرنامج إلى

CPU.PC = CPU.IR.arg;

jz إنقل تنفيذ البرنامج بشرط

if(stack[CPU.SP] == 0) CPU.PC = CPU.IR.arg;

halt إنهاء البرنامج

ولضيق الوقت أكتفي بنقل هذا الكود.

على أنه كان بودي الإسهاب في هذا الموضوع لأعطية حقه

void fetch_execute_cycle()
{ do { /* Fetch */
ir = code[pc++];
/* Execute */
switch (ir.op) {
case HALT : printf( "halt\n" ); break;
case READ_INT : printf( "Input: " );
scanf( "%ld", &stack[ar+ir.arg] ); break;
case WRITE_INT : printf( "Output: %d\n", stack[top--] ); break;
case STORE : stack[ir.arg] = stack[top--]; break;
case JMP_FALSE : if ( stack[top--] == 0 )
pc = ir.arg;
break;
case GOTO : pc = ir.arg; break;
case DATA : top = top + ir.arg; break;
case LD_INT : stack[++top] = ir.arg; break;
case LD_VAR : stack[++top] = stack[ar+ir.arg]; break;
case LT : if ( stack[top-1] < stack[top] )
stack[--top] = 1;
else stack[--top] = 0;
break;
case EQ : if ( stack[top-1] == stack[top] )
stack[--top] = 1;
else stack[--top] = 0;
break;
case GT : if ( stack[top-1] > stack[top] )
stack[--top] = 1;
else stack[--top] = 0;
top--;
break;
case ADD : stack[top-1] = stack[top-1] + stack[top];
top--;
break;
case SUB : stack[top-1] = stack[top-1] - stack[top];
top--;
break;
case MULT : stack[top-1] = stack[top-1] * stack[top];
top--;
break;
case DIV : stack[top-1] = stack[top-1] / stack[top];
top--;
break;
case PWR : stack[top-1] = stack[top-1] * stack[top];
top--;
break;
default : printf( "%sInternal Error: Memory Dump\n" );
break;
}
}
while (ir.op != HALT);
}

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

سوف أكون مستعد بما أستطيع لإجابة على أسئلتكم.

وأود أن أنبه إلى من يكون عنده مصادر موسعة عن الموضوع إن لا يبخل علينا فهي مهمة بالنسبة لي ولغيري

أرجوكم سامحوني على الركاكة في الاسلوب لأنه أول موضوع كبير بالنسبة لي

تم تعديل هذه المشاركة بواسطة mossa في 4 نوفمبر 2004 في 00:01

#2

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

وتسلم ايدك اخي

#3

لاشكر على واجب

ومستعدين لأي سؤال إن شاء الله

#4

اهو انتوا بقي يا اخ موسي اللي تعقدو (سيبوني بقي بجهلي ) _ بهزر طبعا _ انا الصراحة مش مهتم بالموضوع الاساسي او انا كنت مهتم بيه لحد ما وصلت لكلمة سيبنا من لغات البرمجه وندخل علي بنية الحاسب نفسه طيب اللي انت كتبته ده مكنش binary ولا اسمبلي .امال اللي انت كتبته ده ايه .انا معرفش اي حا جه عن بنية الحاسب الاساسية !

ممكن تديني مفتاح اتعلم بيه الموضوع ده؟

تم تعديل هذه المشاركة بواسطة طارق إبراهيم في 6 نوفمبر 2004 في 06:45

لا اله الا الله
#5

يهمك البرنامج إذا كنت برمجت في مجال الCompiler

أو ماشابة

وتريد تنفيذ ناتج الترجمة

والملاحظ أن جمع لغات البرمجة الحديثة تعتمد على VM

مثل

java

.net

وجميع نظم قواعد البيانات

أو أن أقول أن الموضوع ليس سهلاً وإنما يحتاج بعض الأساسيات

هذا الموضوع مغلق.

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