
تدور هذه القصة حول نهج غير قياسي لتطوير تطبيقات Android. هناك شيء واحد لتثبيت Android Studio وكتابة "Hello، World" في Java أو Kotlin. لكنني سأظهر كيف يمكن تنفيذ نفس المهمة بشكل مختلف.
نذكرك: لجميع قراء "Habr" - خصم بقيمة 10،000 روبل عند التسجيل في أي دورة تدريبية في Skillbox باستخدام الرمز "Habr" الترويجي.
توصي Skillbox بما يلي: الدورة التعليمية عبر الإنترنت "Profession Java-developer" .
كيف يعمل هاتفي الذكي مع نظام التشغيل Android OS؟
أولاً ، خلفية صغيرة. في إحدى الأمسيات اتصل بي صديق يدعى Ariella. سألتني: "اسمع ، كيف يعمل هاتفي الذكي؟ ما بداخلها؟ كيف تعمل الطاقة الكهربائية والوحدات والأصفار العادية على العمل؟ "
لم تكن معرفتي مستجدًا في التطوير ، فقد أنشأت العديد من المشاريع على Arduino ، والتي كانت تتكون من كل من البرامج والأجهزة. ربما لهذا السبب أرادت معرفة المزيد. تمكنت من الإجابة بمساعدة المعرفة التي حصلت عليها في واحدة من دورات علوم الكمبيوتر التي اتخذت في الجامعة.
بعد ذلك ، عملنا معًا لمدة أسبوعين ، حيث أراد Ariella معرفة كيفية عمل طوب التكنولوجيا الإلكترونية ، أي عناصر أشباه الموصلات ، بما في ذلك الترانزستورات. بعد ذلك ، ذهبنا إلى مستوى أعلى: لقد أوضحت لها كيفية إنشاء بوابات منطقية ، على سبيل المثال ، NAND (منطقي AND) بالإضافة إلى NOR (منطقي أو OR) باستخدام مزيج محدد من الترانزستورات.
لقد بحثنا في العناصر المنطقية لأنواع مختلفة ، وجمعناها لإجراء حسابات (على سبيل المثال ، إضافة رقمين ثنائيين) وخلايا الذاكرة (المشغلات). عندما أصبح كل شيء واضحًا ، بدأوا في تطوير معالج بسيط (وهمي) ، حيث كان هناك سجلان للأغراض العامة وتعليمان بسيطان (إضافة هذه السجلات). لقد كتبنا برنامجًا بسيطًا يضاعف هذين الرقمين.
بالمناسبة ، إذا كنت مهتمًا بهذا الموضوع ، فاقرأ الإرشادات الخاصة بإنشاء جهاز كمبيوتر 8 بت من البداية. وهذا ما يفسر كل شيء تقريبا ، من الأساسيات. أتمنى أن أقرأها في وقت سابق!
مرحبا أندرويد!
بعد الانتهاء من جميع مراحل الدراسة ، بدا لي أن لدى أريئيل معرفة كافية لفهم كيفية عمل معالج الهاتف الذكي. هاتفها الذكي هو Galaxy S6 Edge ، الذي أساسه بنية ARM (كما في الواقع ، مع معظم الهواتف الذكية). قررنا كتابة تطبيق "Hello، World" لنظام Android ، ولكن بلغة التجميع.
.text .globl _start _start: mov %r0, $1 // file descriptor number 1 (stdout) ldr %r1, =message mov %r2, $message_len mov %r7, $4 // syscall 4 (write) swi $0 mov %r0, $0 // exit status 0 (ok) mov %r7, $1 // syscall 1 (exit) swi $0 .data message: .ascii "Hello, World\n" message_len = . - message
إذا لم تصادف رمز المجمّع من قبل ، فقد يخيفك هذا الحظر. لكن لا بأس ، دعنا نحلل الشفرة معًا.
لذلك ، يتكون برنامجنا من جزأين. الأول هو النص مع تعليمات رمز الجهاز ، والثاني هو المتغيرات ، والخطوط ، وغيرها من المعلومات (بدءا من السطر 15). قسم .text عادةً للقراءة فقط ، و .data قابلة للكتابة أيضًا.
في السطر 2 ، نقوم بتعريف دالة عمومية تسمى _start. هذا هو نقطة الدخول إلى التطبيق. يبدأ نظام التشغيل في تنفيذ التعليمات البرمجية من هذه النقطة. يتم تعريف تعريف الوظيفة في السطر 4.
بالإضافة إلى ذلك ، تقوم الوظيفة بعمل شيئين آخرين. في الأسطر 5-9 ، يتم عرض الرسالة على الشاشة ؛ في الأسطر 11-13 ، ينتهي البرنامج. حتى إذا قمت بحذف الأسطر 11-13 ، فسيقوم البرنامج بإخراج خط "Hello، World" الخاص بنا والخروج. ومع ذلك ، لن يكون الإخراج صحيحًا ، لأن البرنامج سينتهي بخطأ ما. بدون سطور 11-13 ، سيحاول التطبيق تنفيذ تعليمة غير صالحة.
يتم عرض الطباعة باستخدام وظيفة النظام "استدعاء النظام" في نظام التشغيل. في التطبيق ، ندعو وظيفة الكتابة (). نوضحها عند تحميل القيمة 4 في سجل المعالج بالاسم r7 (السطر 8). بعد ذلك ، يتم تنفيذ التعليمة swi $ = 0 (السطر 9) ، حيث يوجد انتقال مباشر إلى kernel Linux ، والذي يعد أساس Android.
بالنسبة إلى معلمات استدعاء النظام ، يتم إرسالها عبر سجلات أخرى. على سبيل المثال ، يعرض r0 عدد واصف الملف الذي نحتاج إلى طباعته. نضع القيمة 1 هناك (السطر 5) ، مع الإشارة إلى الإخراج القياسي (stdout) ، أي الإخراج إلى الشاشة.
يشير r1 إلى عنوان ذاكرة البيانات التي نرغب في كتابتها ، لذلك نقوم فقط بتحميل عنوان السلسلة "Hello، World" (السطر 6) في هذه المنطقة ، ويظهر السجل r2 عدد البايتات التي نريد كتابتها. في برنامجنا ، يتم ضبطه على message_len (السطر 7) ، محسوب على السطر 18 باستخدام بناء جملة خاص: يشير رمز النقطة إلى عنوان الذاكرة الحالي. لهذا السبب. - تشير الرسالة إلى عنوان الذاكرة الحالي مطروحًا منه عنوان الرسالة. حسنًا ، نظرًا لأننا نعلن message_len مباشرةً بعد الرسالة ، يتم حساب كل هذا على أنه طول الرسالة.
إذا كتبت رمز الأسطر من 5 إلى 9 باستخدام C ، فستحصل على ما يلي:
#define message "Hello, World\n" write(1, message, strlen(message));
إغلاق البرنامج أسهل قليلاً. للقيام بذلك ، نقوم ببساطة بتسجيل رمز الخروج في السجل r0 (السطر 11) ، وبعد ذلك نضيف القيمة 1 ، وهي رقم استدعاء وظيفة نظام الخروج () ، إلى r7 (السطر 12) ، ثم ندعو النواة مرة أخرى (السطر 13).
يمكن العثور على قائمة كاملة بمكالمات نظام أندرويد وأرقامها في
الكود المصدري
لنظام التشغيل . يوجد أيضًا تطبيق
للكتابة () والخروج () لاستدعاء وظائف النظام المناظرة.
وضع البرنامج معا
من أجل ترجمة مشروعنا ، ستحتاج إلى Android NDK (Native Development Kit). أنه يحتوي على مجموعة من المجمعين وأدوات البناء لمنصة ARM. يمكنك تنزيله من الموقع الرسمي ، وتثبيته ، على سبيل المثال ، من خلال Android Studio.

بعد تثبيت NDK ، نحتاج إلى ملف arm-linux-androideabi-as ، وهذا أداة لتجميع ARM. إذا قمت بالتنزيل عبر Android Studio ، فابحث عنه في مجلد Android SDK. عادة ما يكون موقعه هو
ndk-bundle \ toolchains \ arm-linux-androideabi-4.9 \ prebuilt \ windows-x86_64 \ bin.بعد العثور على المجمع ، احفظ ما هو مكتوب في ملف يسمى hello.s ، ثم قم بتشغيل الأمر التالي لتحويله إلى رمز الجهاز:
arm-linux-androideabi-as -o hello.o hello.sهذه العملية بإنشاء ملف كائن ELF يسمى hello.o. لتحويله إلى ملف ثنائي يمكنه العمل على جهازك ، اتصل بالرابط:
arm-linux-androideabi-ld -o hello hello.oالآن لدينا ملف hello يحتوي على برنامج جاهز للاستخدام.
قم بتشغيل التطبيق على جهازك
عادةً ما يتم توزيع تطبيقات Android بتنسيق .apk. هذا نوع خاص من الملفات المضغوطة يتضمن فئات Java (نعم ، يمكنك الكتابة باستخدام C / C ++ ، ولكن يجب أن تكون Java نقطة الدخول).
لتجنب المشاكل عند بدء تشغيل التطبيق ، تم استخدام adb في المثال ، والذي سمح لنا بنسخه إلى المجلد المؤقت لجهاز Android الخاص بنا. بعد ذلك ، أطلقنا قذيفة adb من أجل إطلاق التطبيق وتقييم النتيجة:
بنك التنمية الآسيوي دفع مرحبا / البيانات / المحلية / تمة / مرحبا
شل بنك التنمية الآسيوي chmod + x / data / local / tmp / helloوأخيراً ، قم بتشغيل التطبيق:
شل بنك التنمية الآسيوي / البيانات / المحلية / تمة / مرحباماذا تكتب؟
الآن لديك بيئة عمل مماثلة لتلك التي كانت لدى Ariella. أمضت عدة أيام في دراسة مجمّع ARM ، ثم توصلت إلى مشروع بسيط - هذه هي لعبة Sven Boom (اختلافات Fizz Buzz في الأصل عن إسرائيل). يحسب اللاعبون بدورهم وفي كل مرة يتم تقسيم الرقم على 7 أو يحتوي على الرقم 7 ، يجب أن يقولوا "بوم" (ومن هنا جاء اسم اللعبة).
تجدر الإشارة إلى أن برنامج اللعبة ليس بهذه المهمة السهلة. كتب Ariella طريقة كاملة تعرض الأرقام ، رقم واحد في كل مرة. نظرًا لأنها كتبت كل شيء في المجمع دون استدعاء وظائف مكتبة C القياسية ، فقد استغرق الأمر عدة أيام لحلها.
يتوفر أول برنامج Ariella لـ Adnroid
هنا . بالمناسبة ، بعض معرفات الرمز في التطبيق هي في الواقع كلمات عبرية (على سبيل المثال ، _sifra_ahrona).
تعد كتابة تطبيق Android في أداة التجميع طريقة جيدة للتعرف على بنية ARM بشكل أفضل ، وكذلك لفهم المطبخ الداخلي للأداة التي تستخدمها يوميًا بشكل أفضل. أقترح عليك القيام بذلك عن كثب ومحاولة إنشاء تطبيق مجمع صغير لجهازك. قد تكون لعبة بسيطة أو أي شيء آخر.
توصي Skillbox بما يلي: