في سعيك لتحويل لغة الجمعية (assembly) إلى رمز الآلة (machine code) باستخدام مترجم MINGW، تبدو الفكرة الخاصة بك بشأن استخدام هيكل بيانات (struct) مع قائمة لكل تعليمة وقيمتها المعادة كوسيلة فعالة. ومع ذلك، تواجه بعض الصعوبات في التنفيذ وتظهر لك رسائل خطأ مثل “request for member opcode in something not a structure”.
لتوضيح الأمور، يجب عليك إجراء بعض التعديلات في الشيفرة البرمجية. أولاً وقبل كل شيء، لديك خطأ في تعريف الدالة get_inst
، حيث يجب أن يكون النوع الذي تعيده هو Instruction
بدلاً من Instruction
.
-
تفاصيل البيانات المنطقية في لغة Go19/01/2024
-
فهم حجم وتحويل المؤشرات في C++19/03/2024
-
تحليل درجات الدقة لتصنيف الفئات03/04/2024
بالإضافة إلى ذلك، يتعين عليك استخدام النقاط (dots) بدلاً من النقاط التي قمت بكتابتها في محاولة الطباعة في دالة main2
. هذا لأنك تتعامل مع مصفوفة من الهيكل (struct array)، وليس مع هيكل فردي.
أدناه، ستجد الشيفرة البرمجية المعدلة بما يلزم:
c#include
#include
struct _Instruction {
char mnemonic[10];
unsigned char opcode;
};
typedef struct _Instruction Instruction;
Instruction instruction_list[] = {
{"mov", 0x01},
{"add", 0x04},
{"sub", 0x05},
{"mul",0x06},
{"div", 0x07},
{"and",0x08},
{"or",0x09},
{"xor",0x0a},
{"cmp",0x0b},
{"", -1},
};
Instruction get_inst(char mnemonic[]);
int main(int argc, char *argv[])
{
char* instruction = argv[1];
Instruction inst = get_inst(instruction);
printf("%s ; 0x%02x", inst.mnemonic, inst.opcode);
return 0;
}
Instruction get_inst(char mnemonic[])
{
int i;
for(i=0; instruction_list[i].opcode != -1; i++)
{
if(!strcmp(instruction_list[i].mnemonic, mnemonic))
{
return instruction_list[i];
}
}
// إذا لم يتم العثور على التعليمة، يمكنك إعادة هيكل فارغ أو التعامل بطريقة أخرى حسب احتياجاتك
Instruction empty_inst = {"", -1};
return empty_inst;
}
الآن، يجب أن تعمل الشيفرة بشكل صحيح وتقوم بطباعة النتيجة المتوقعة عند استخدام الأمر ./convert.exe mov
، حيث يطبع “mov ; 0x01”.
بهذه التعديلات، يتوقع أن تكون قادرًا على مواصلة تحويل التعليمات الفردية من لغة الجمعية إلى رمز الآلة بنجاح.
المزيد من المعلومات
في رحلتك لتحويل لغة الجمعية إلى رمز الآلة باستخدام مترجم MINGW، يجب عليك فهم الشيفرة البرمجية بشكل أعمق لضمان فاعلية عملية التحويل. لنقم بمراجعة بعض النقاط الرئيسية في الشيفرة:
-
هيكل التعليمات (Instruction Structure):
- تم تعريف هيكل
Instruction
بطريقة صحيحة، حيث يحمل كل عنصر فيه اسمًا (mnemonic
) وقيمة (opcode
). استفادت من هذا الهيكل لتخزين معلومات كل تعليمة.
- تم تعريف هيكل
-
قائمة التعليمات (Instruction List):
- تم إنشاء قائمة
instruction_list
لتخزين جميع التعليمات مع قيم رموز الآلة المقابلة. تم استخدام-1
كعلامة نهاية للقائمة.
- تم إنشاء قائمة
-
البحث عن التعليمة (get_inst Function):
- تم تنفيذ دالة
get_inst
للبحث عن التعليمة المطلوبة في قائمة التعليمات. إذا تم العثور عليها، يتم إرجاع الهيكل المقابل لها.
- تم تنفيذ دالة
-
الدالة الرئيسية (main Function):
- الدالة الرئيسية تقوم بقبول وسيطة واحدة (instruction) من خط الأوامر، ثم تستخدم دالة
get_inst
للحصول على التعليمة المقابلة. بعد ذلك، يتم طباعة اسم التعليمة ورمز الآلة المتوقع.
- الدالة الرئيسية تقوم بقبول وسيطة واحدة (instruction) من خط الأوامر، ثم تستخدم دالة
-
منطق إيقاف البحث في
get_inst
:- تم استخدام قيمة
-1
كعلامة نهاية في قائمة التعليمات لإيقاف البحث. تأكد من أنها تعمل بشكل صحيح مع التصميم الخاص بك.
- تم استخدام قيمة
-
مقارنة السلاسل (
strcmp
):- تم استخدام دالة
strcmp
لمقارنة السلاسل للعثور على التعليمة المطلوبة. تأكد من أن الأسماء مكتوبة بشكل صحيح ومطابقة للقائمة.
- تم استخدام دالة
-
التفاعل مع الأخطاء:
- في حالة عدم العثور على التعليمة، يتم إعادة هيكل فارغ (
empty_inst
)، يمكنك تخصيص هذا التصرف حسب احتياجاتك.
- في حالة عدم العثور على التعليمة، يتم إعادة هيكل فارغ (
-
الطباعة (
printf
):- تم استخدام
printf
لطباعة اسم التعليمة ورمز الآلة المتوقع بشكل جيد. تأكد من تصحيح أي خطأ في النص الذي يتم طباعته.
- تم استخدام
باستخدام هذه النقاط كدليل، يجب أن تكون قادرًا على مواصلة تحويل التعليمات الفردية من لغة الجمعية إلى رمز الآلة بنجاح. تأكد من تكرار العملية مع مزيد من التعليمات واختبار الشيفرة بشكل دقيق لضمان صحة التحويل.