في عملية كتابة أداة تحميل التمهيد STM8uLoader للمتحكم الدقيق STM8 ، أصبح من الضروري قياس عمق المكدس.
دعونا نطرح الأسئلة:
- ماذا يحدث إذا حاولت دفع المزيد من المعلومات حول المكدس أكثر من عمقها؟
- ماذا يحدث إذا حاولت استخراج معلومات من المكدس أكثر من وضعها؟
- ماذا يحدث إذا قمت بتهيئة مؤشر مكدس SP بعنوان يتجاوز حدود المكدس؟
قد تختلف ذاكرة RAM وعمق المكدس باختلاف طرازات STM8.
للدراسة ، تم اختيار نموذج STM8S103F3.
توفر وثائق STM8S103F3 البيانات التالية:
- عمق المكدس 513 بايت ؛
- عند إعادة التعيين ، تتم تهيئة مؤشر SP إلى 0x03FF (RAM END) ؛
- ينمو المكدس في اتجاه تناقص العناوين.
يظهر الحساب أن الحد الأدنى من المكدس هو:
0x03FF - 513 = 0x01FF
لكسر هذا الحد ، تحتاج إلى دفع بضع أكثر من 513 بايت على المكدس.
محتويات المكدس لا تهمنا. يكفي أن تعرف محتويات المؤشر إلى مكدس SP ، الذي يجب أن يحتوي على عنوان خلية ذاكرة RAM التالية غير المستخدمة.
سنقوم بوضع البايتات بالتتابع مع أي أمر دفع (على سبيل المثال ، الضغط A) وقبل كل خطوة نرسل محتويات أعلى SPH وأقل بايت SPL من مؤشر مكدس SP إلى UART.
خوارزمية الإجراء:
قم بتهيئة مؤشر المكدس بقيمة 0x03FF وتكوين UART ؛
2 نحن ننتظر أي بايت من البرنامج النهائي ؛
3 بايت مقبولة ؛
4 إرسال محتويات مؤشر SP إلى UART ؛
5 ندفع محتويات البطارية إلى المكدس باستخدام الأمر push A ؛
6 إذا كانت دورات الإرسال أقل من 64 ، فانتقل إلى الخطوة 4 ؛
7 إذا كانت دورات إرسال 64 ، انتقل إلى الخطوة 2.
; UART 9600/8N1 mov UART1_BRR2, #$00 ; mov UART1_BRR1, #$0D ; / mov UART1_CR2, #%00001100 ; SP $03FF ldw X, #$03FF ; X <= RAM END ldw SP, X ; SP <= X ; wait_rx_byte: btjf UART1_SR, #5, wait_rx_byte ; ld A, UART1_DR ; bset PB_DDR,#5 bset PB_CR1,#5 ldw Y, #64 ; Y <= 64 stack_cycle: ldw X, SP ; X <= SP ; SPH UART ; rlwa X ; A <- XH <- XL <- A ld A, XH ; A <- XH ld UART1_DR, A ; UART1_DR <= A wait_tx_byte_XH: btjf UART1_SR, #7, wait_tx_byte_XH ; SPL UART ; rlwa X ; A <- XH <- XL <- A ld A, XL ; A <- XL ld UART1_DR, A ; UART1_DR <= A wait_tx_byte_XL: btjf UART1_SR, #7, wait_tx_byte_XL ; A push A ; M(SP
نلاحظ كيف يقبل البرنامج الطرفي بالتسلسل محتويات مؤشر SP بدءًا من 0x03FF:
03 FF 03 FE 03 FD 03 FC 03 FB 03 FA 03 F9 03 F8 03 F7 03 F6 03 F5 03 F4 03 F3 03 F2 03 F1 03 F0 03 EF 03 EE 03 ED 03 EC 03 EB 03 EA 03 E9 03 E8 03 E7 03 E6 03 E5 03 E4 03 E3 03 E2 03 E1 03 E0 03 DF 03 DE 03 DD 03 DC 03 DB 03 DA 03 D9 03 D8
بعد أن تصل القيمة إلى 0x01FF (حد مكدس محسوب سابقًا)
أخذ مؤشر SP مرة أخرى القيمة 0x03FF (المكدس مغلق في حلقة)
وبدأت الكتابة فوق أقدم البيانات
02 0F 02 0E 02 0D 02 0C 02 0B 02 0A 02 09 02 08 02 07 02 06 02 05 02 04 02 03 02 02 02 01 02 00 01 FF 03 FF 03 FE 03 FD 03 FC 03 FB 03 FA 03 F9 03 F8 03 F7 03 F6 03 F5 03 F4 03 F3 03 F2 03 F1 03 F0 03 EF 03 EE 03 ED 03 EC 03 EB 03 EA 03 E9
الآن دعونا نرى كيف تتصرف محتويات مؤشر SP إذا حاولنا استرداد المحتويات بشكل غير محدود من المكدس.
خوارزمية الإجراء:
قم بتهيئة مؤشر المكدس بقيمة 0x03FF وتكوين UART ؛
2 نحن ننتظر أي بايت من البرنامج النهائي ؛
3 بايت مقبولة ؛
4 نقوم باستخراج المحتويات من المكدس باستخدام الأمر "pop A" إلى البطارية ؛
5 يرسل محتويات مؤشر SP إلى UART ؛
6 إذا كانت دورات الإرسال أقل من 64 ، فانتقل إلى الخطوة 3 ؛
7 إذا كانت دورات إرسال 64 ، انتقل إلى الخطوة 2.
يتم تبديل البندين 4 و 5 من الخوارزمية والأمر “push A” بالأمر “pop A”.
على الرغم من حقيقة أننا قمنا بتهيئة مؤشر SP بالقيمة 0x03FF بالفعل بعد الأمر pop الأول الأول ، فقد أخذ المؤشر القيمة 0x01FF واستمر في الزيادة نحو 0x03FF.
01 FF 02 00 02 01 02 02 02 03 02 04 02 05 02 06 02 07 02 08 02 09 02 0A 02 0B 02 0C 02 0D 02 0E 02 0F 02 10 02 11 02 12 02 13 02 14 02 15 02 16 02 17 02 18 02 19 02 1A 02 1B 02 1C 02 1D 02 1E 02 1F 02 20 02 21 02 22 02 23 02 24 02 25 02 26
الوصول إلى القيمة 0x03FF. بعد الأمر pop التالي ، افترض المؤشر مرة أخرى القيمة 0x01FF واستمر في الزيادة باتجاه 0x03FF.
03 EF 03 F0 03 F1 03 F2 03 F3 03 F4 03 F5 03 F6 03 F7 03 F8 03 F9 03 FA 03 FB 03 FC 03 FD 03 FE 03 FF 01 FF 02 00 02 01 02 02 02 03 02 04 02 05 02 06 02 07 02 08 02 09 02 0A 02 0B 02 0C 02 0D 02 0E 02 0F 02 10 02 11 02 12 02 13 02 14 02 15
في الاتجاه المعاكس ، مع وجود عدد مفرط من تعليمات pop (w) ، يتم إغلاق المكدس أيضًا في حلقة 513 بايت.
المكدس في STM8S103F3 خطي حتى تقوم بكسر أحد حدوده 0x01FF أو 0x03FF.
بمجرد كسر أحد الحدود ، يصبح المكدس حلقة 513 بايت.
لا يهم مكان الحلقة (في العناوين 0x01FF ... 0x03FF) في الجزء العلوي / السفلي من المكدس ، يمكننا وضع عدد غير محدود من وحدات البايت على المكدس ، ولكن لا يمكننا استخراج أكثر من 513 بايت غير تالف (أحدثها).
الآن بعد أن تم ترجمة المكدس عند 0x01FF ... 0x03FF ، حان الوقت لكسر هذا النطاق عند تهيئة مؤشر SP.
في الخطوة 1 من الإجراء الأول ، نستبدل القيمة 0x03FF لتهيئة مؤشر SP بالقيمة 0x01FE.
نلاحظ كيف ذهب المكدس من العنوان 0x01FE في اتجاه تناقص العناوين.
01 FE 01 FD 01 FC 01 FB 01 FA 01 F9 01 F8 01 F7 01 F6 01 F5 01 F4 01 F3 01 F2 01 F1 01 F0 01 EF 01 EE 01 ED 01 EC 01 EB 01 EA 01 E9 01 E8 01 E7 01 E6 01 E5 01 E4 01 E3 01 E2 01 E1 01 E0 01 DF 01 DE 01 DD 01 DC 01 DB 01 DA 01 D9 01 D8 01 D7
بعد الوصول إلى العنوان 0x0000 ، خرج المكدس من ذاكرة الوصول العشوائي (RAM) ودخل خلايا ذاكرة FLASH التي لا يمكن الوصول إليها إلى STM8S103F3.
00 16 00 15 00 14 00 13 00 12 00 11 00 10 00 0F 00 0E 00 0D 00 0C 00 0B 00 0A 00 09 00 08 00 07 00 06 00 05 00 04 00 03 00 02 00 01 00 00 FF FF FF FE FF FD FF FC FF FB FF FA FF F9 FF F8 FF F7 FF F6 FF F5 FF F4 FF F3 FF F2 FF F1 FF F0 FF EF
لا يمكن الحديث عن مكالمات أو انقطاعات فرعية بعد خروج المؤشر من ذاكرة RAM. صحيح ، في مكان ما في أعماق المكدس ، لا تزال البيانات "القديمة" باقية ، والتي كانت محظوظة ليتم حفظها في ذاكرة RAM.
الآن دعنا نحاول استرداد البيانات من المكدس مع تهيئة "ممنوع" (خارج النطاق 0x01FF ... 0x03FF) لمؤشر SP.
لنبدأ بعناوين خارج RAM. في الخطوة 1 من الإجراء الثاني ، نستبدل القيمة 0x03FF لتهيئة المؤشر SP بالقيمة 0xFFF8.
نلاحظ كيف ذهب المكدس إلى ذاكرة RAM.
FF E9 FF EA FF EB FF EC FF ED FF EE FF EF FF F0 FF F1 FF F2 FF F3 FF F4 FF F5 FF F6 FF F7 FF F8 FF F9 FF FA FF FB FF FC FF FD FF FE FF FF 00 00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0A 00 0B 00 0C 00 0D 00 0E 00 0F 00 10
عبر المكدس الحد الأدنى 0x01FF ، دخل المكدس أراضيه.
01 E9 01 EA 01 EB 01 EC 01 ED 01 EE 01 EF 01 F0 01 F1 01 F2 01 F3 01 F4 01 F5 01 F6 01 F7 01 F8 01 F9 01 FA 01 FB 01 FC 01 FD 01 FE 01 FF 02 00 02 01 02 02 02 03 02 04 02 05 02 06 02 07 02 08 02 09 02 0A 02 0B 02 0C 02 0D 02 0E 02 0F 02 10
بعد الوصول إلى العنوان 0x03FF ، تم إغلاق المكدس في حلقة.
03 E9 03 EA 03 EB 03 EC 03 ED 03 EE 03 EF 03 F0 03 F1 03 F2 03 F3 03 F4 03 F5 03 F6 03 F7 03 F8 03 F9 03 FA 03 FB 03 FC 03 FD 03 FE 03 FF 01 FF 02 00 02 01 02 02 02 03 02 04 02 05 02 06 02 07 02 08 02 09 02 0A 02 0B 02 0C 02 0D 02 0E 02 0F
الاستنتاجات:
المكدس في STM8S103F3 قادر على أداء واجباته فقط ضمن النطاق 0x01FF ... 0x03FF.
للحصول على أكبر عمق خطي ، يجب تهيئة مؤشر مكدس SP في STM8S103F3 إلى 0x03FF.
المكدس في STM8S103F3 خطي حتى تقوم بكسر الحد السفلي 0x01FF.
بمجرد كسر الحد السفلي ، يصبح المكدس حلقة 513 بايت.