تقنية

عناوين Intel HEX: لماذا يصلح السجل ويتغير موضع بايتاته؟

حقول سجلاتنا الستة وخريطة البايتات السبعة الناتجة.
فصلنا سجلاتنا إلى الحقول الخمسة بعد النقطتين؛ الخرائط السفلية نواتج مثالنا.

سجل04 يحدد أساس العنوان اللاحق؛ وفحص السجل لا يثبت بقاء خريطة العناوين عند تبديل ترتيب الأسطر. [1]

الخلاصة السريعة

  • ملفنا ستة سجلات، تحمل سجلات البيانات فيه سبعة بايتات فقط.
  • وصل الزوج 11 22 إلى العنوانين 00000010 و00000011 في القراءة الأصلية.
  • وصلت AA BB CC إلى 00010010 و00010011 و00010012، بعد الأساس الذي اخترناه أولا.
  • نقل سجل الأساس الثاني إلى موضع أبكر نقل الثلاثية إلى 00020010–00020012، مع بقاء فحص كل سجل ناجحا.
  • تغيير BB الأخير في السطر الأول إلى BA أفشل الفحص؛ تجربة الترتيب وتجربة التلف أعطتا نتيجتين مختلفتين.

احفظ ستة أسطر بترتيبها

أنشئ ملفا نصيا باسم address-case.hex بالأسطر التالية. كل الأرقام والحروف داخل هذا الملف ست عشرية. اخترنا ثلاث مجموعات بيانات: 11 22، ثم AA BB CC، ثم 33 44. لا يمثل الملف برنامجا لجهاز؛ الغرض من قيمه أن نرى أين تظهر كل مجموعة في خريطة القراءة.

:020010001122BB
:020000040001F9
:03001000AABBCCBC
:020000040002F8
:02003000334457
:00000001FF
[1]

أساس سجل04 هو وسيطه مزاحا16بتا؛ يضاف إليه إزاحة سجل البيانات. وقبل أي أساس معلن نستخدم الصفر. [1]

في ملفنا، أعطى 0001 الأساس 00010000، وأعطى 0002 الأساس 00020000. جمع الأول مع 0010 أعطى 00010010؛ وجمع الثاني مع 0030 أعطى 00020030.

اقرأ الملف وأخرج خريطته

ضع البرنامج التالي بجانب الملف، وشغله باستخدام Python من المجلد نفسه، دون خيار -O. نفذناه على Python 3.12.14. هذا قارئ تعليمي محدود بأنواع سجل 00/01/04 وحالاتنا؛ لم نبن أداة عامة لقبول كل تنويعات HEX. يطبع عناوين وقيمًا ولا يرسل شيئا إلى جهاز.

from pathlib import Path
base=0;memory={}
for line in Path("address-case.hex").read_text().splitlines():
    b=bytes.fromhex(line[1:])
    assert line.startswith(":") and len(b)==b[0]+5
    assert sum(b)%256==0
    n=b[0];offset=int.from_bytes(b[1:3],"big")
    kind=b[3];data=b[4:-1]
    if kind==4:
        assert n==2 and offset==0
        base=int.from_bytes(data,"big")<<16
    elif kind==0:
        for i,value in enumerate(data):
            address=(base+offset+i)&0xFFFFFFFF
            assert address not in memory
            memory[address]=value
    elif kind==1:
        assert n==0 and offset==0
        break
    else:
        raise ValueError(kind)
for address,value in sorted(memory.items()):
    print(f"{address:08X} {value:02X}")
[1]

كان السجل الناتج سبعة أسطر، لا ستة: عدد أسطر الإدخال مختلف عن عدد بايتات البيانات في مثالنا. طابقت الخريطة العناوين والقيم المرسومة أدناه. وقارناها أيضا بقارئ مستقل يعالج أزواج الحروف واحدا واحدا ويجمع بايتات العنوان حسابيا، بدلا من استعمال تحويل البرنامج نفسه.

اختبر مجموع السطر الأول

قيم سطرنا الأول بالعشري هي 2، 0، 16، 0، 17، 34، 187. مجموعها 256، وباقي قسمته على 256 يساوي صفرا. القيمة الأخيرة BB هي 187؛ تبديلها وحدها إلى BA أعطى 186، فأصبح المجموع 255 وفشل شرط البرنامج.

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

قدم الأساس الثاني واترك السجلات سليمة

عد إلى النسخة الأصلية. انقل السطر الرابع كاملا ليصبح ثالثا، فتكون أرقام الأسطر الأصلية بعد الترتيب 1، 2، 4، 3، 5، 6. لم نغير أي حرف داخل سجل. هذه المرة نجح شرط المجموع في السجلات الستة، لكن الثلاثية AA BB CC صارت تحت الأساس 00020000.

خريطتان للبايتات السبعة: ثلاثة عناوين وسطى تغيرت عند تقديم سجل الأساس الثاني، وبقي الزوجان الآخران في موضعيهما.
قيم البايتات ثابتة في الاختبارين؛ التظليل يحدد الثلاثة التي اختلف عنوانها.

زاد عنوان كل بايت من الثلاثية بمقدار 00010000، أي 65536 بالعشري. بقي عدد البايتات سبعة، وبقيت قيمها نفسها. اخترنا للزوج الأخير إزاحة 0030 كي لا تتصادم عناوينه مع 0010 و0011 و0012 التي استعملتها الثلاثية بعد النقل؛ وإلا دخل سؤال التداخل في تجربتنا بدلا من تغيير العنوان وحده.

قارن الخريطة مع السجل

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

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

المراجع

  1. Microchip Hexmate: Intel HEX file specification — الصفحات المطبوعة7–10.
أُعد المثال محليا في13 أكتوبر2026.

أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي وراجعته أدوات ذكاء اصطناعي. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.