العنوان 0 يتم الكتابة فوقه بواسطة Null Pointer على HCS08
سؤال
على جهاز HCS08 Micro المكون من 8 بت ، كلما أسمي وظيفة مكتبة تُرجع القيم إلى المؤشرات التي أعمرها ، وأنا لا أريدها حقًا ، ألقيت في خالية ، على سبيل المثال
UART_SendBlock((char *)txstr, strlen(txstr), NULL);
نوع الحجة الأخيرة هو uint16_t *
وإرجاع عدد الأحرف المرسلة بالفعل ، وهي قيمة لا أهتم بها.
ومع ذلك ، كنت أواجه مشاكل مع Port A على Micro التي يتم فيها أن يتم استدعاء هذه الوظيفة ، وأشارني تصحيح الأخطاء إلى هذه الحجة التي تفسد الأشياء. سجلات تكوين المنفذ A تعيش في عناوين 0x0000 و 0x0001 ، وهو المكان NULL
(الملقب ب (void *)0
) نقاط. اعتقدت NULL
كان السحر بطريقة ما حيث لم يفعل أي شيء في الواقع ، لكنه لا يبدو كذلك.
يشعر الحل البديل بالاختراق حقًا:
#define MNUL (void *)(&mynull)
uint32_t mynull;
هل هناك حل أفضل؟ حاولت تحديد MNUL إلى شريحة من الذاكرة غير المستخدمة على معالجتي ، ولكن هذا يسبب إعادة ضبط فورية.
المحلول
ما لم تكن الوثائق الخاصة بـ Uart_SendBlock تنص على أن تمريره مؤشرًا فارغًا على ما يرام ، فربما تحصل على سلوك غير محدد إذا قمت بذلك - وفي هذه الحالة يبدو أن الوظيفة تكتب فقط إلى العنوان الذي تمريره ، العنوان 0 - الذي سيخضع "غير محدد" سلوك".
ما عليك سوى الاتصال به بمعلمة ، لا يوجد سبب ليكون "ذكيًا" حيال ذلك.
uint16_t unused_16;
UART_SendBlock((char *)txstr, strlen(txstr), &unused_16);
إذا كنت مقيدًا بالموارد ، فقم unused_16
عالمي وإعادة استخدامه في أماكن أخرى
نصائح أخرى
تحاول الوظيفة كتابة قيمة في أي مكان آخر نقاط الوسيطة. أنت تمر في NULL (0x0000) ، لذلك يتم كتابة النتيجة إلى موقع الذاكرة 0x0000 ، أو منفذك A. عادة (بشكل عام البرمجة) ستتحقق الوظيفة من الوسيطة ولا تحاول الكتابة إلى الموقع إذا كان NULL ، ولكن يبدو أن هذه الوظيفة لا تتبع تلك الاتفاقية. تحتاج إلى تخصيص متغير للوظيفة لكتابة نتائجها ، حتى لو لم تستخدمها.