سؤال

في رمز التجميع التالي الذي ألقاه باستخدام objdump:

lea    0x0(%esi,%eiz,1),%esi

ما هو السجل %eiz؟ ماذا يعني الرمز السابق؟

هل كانت مفيدة؟

المحلول

يرى لماذا يعقد GCC Lea eiz؟:

فيما يبدو %eiz هو تسجيل زائف يقييم فقط إلى الصفر في جميع الأوقات (مثل r0 على MIPS).

...

لقد وجدت في النهاية منشورًا بريديًا من قبل BinuTils Guru Ian Lance Taylor الذي يكشف الإجابة. في بعض الأحيان ، تقوم GCC بإدخال تعليمات NOP في دفق الكود لضمان المحاذاة المناسبة وأشياء من هذا القبيل. تأخذ تعليمات NOP بايت واحد ، لذلك تعتقد أنه يمكنك فقط إضافة أكبر عدد ممكن حسب الحاجة. ولكن وفقًا لإيان لانس تايلور ، فإنه من الأسرع أن تقوم الشريحة بتنفيذ تعليمات طويلة واحدة من العديد من الإرشادات القصيرة. لذا بدلاً من إدخال سبع تعليمات NOP ، فإنهم يستخدمون بدلاً من ذلك LEA Bizarro ، والذي يستخدم سبعة بايت ويعادل بشكل دلالي NOP.

نصائح أخرى

(متأخراً جدًا عن اللعبة ، لكن هذا بدا وكأنه إضافة مثيرة للاهتمام): إنه ليس سجلًا على الإطلاق ، إنه مغلق من تشفير تعليمات Intel. عند استخدام بايت MODRM للتحميل من الذاكرة ، هناك 3 بتات تستخدم لحقل التسجيل لتخزين 8 سجلات ممكنة. ولكن يتم تفسير المكان الذي يتم فيه تفسير ESP (مؤشر المكدس) "من قبل المعالج على أنه" بايت SIB يتبع هذه التعليمات "(أي وضع معالجة ممتد ، وليس مرجعًا إلى ESP). لأسباب معروفة فقط للمؤلفين ، كان مجموعة GNU يمثل دائمًا هذا "صفر حيث سيكون السجل" بخلاف ذلك "كسجل" ٪ eiz ". بناء جملة Intel يسقطه فقط.

يوفر Andy Ross الكثير من التفكير الأساسي ، لكنه للأسف مخطئ أو على الأقل مربكًا حول التفاصيل الفنية. صحيح أن عنوان فعال فقط (%esp) لا يمكن تشفيرها فقط بايت MODR/M بدلاً من فك تشفير (%esp), ، يتم استخدامه للإشارة إلى أنه يتم تضمين بايت SIB أيضًا. ومع ذلك ، فإن %eiz لا يتم استخدام المسجلة الزائفة دائمًا مع بايت SIB لتمثيل بايت SIB.

يحتوي بايت SIB (المقياس/الفهرس/القاعدة) على ثلاث قطع: الفهرس (سجل مثل AS %eax أو %ecx يتم تطبيق المقياس على) ، والمقياس (قوة من اثنين من 1 إلى 8 أن سجل الفهرس يتم ضربه بواسطة) ، والقاعدة (سجل آخر يضاف إلى الفهرس المقوس). هذا ما يسمح بتعليمات مثل add %al,(%ebx,%ecx,2) (كود الآلة: 00 04 4b - OPCODE ، MODR/M ، SIB (لاحظ NO ٪ eiz سجل على الرغم من استخدام بايت SIB)) (أو في بناء جملة Intel ، "إضافة BYTE PTR [ECX*2+EBX] ، AL").

لكن، %esp لا يمكن استخدامها كسجل الفهرس في بايت SIB. بدلاً من السماح لهذا الخيار ، تضيف Intel بدلاً من ذلك خيارًا لاستخدام السجل الأساسي كما هو مع عدم وجود تحجيم أو فهرسة. وبالتالي فإن الغموض بين حالة add %al,(%ecx) (كود الآلة: 00 01 - Opcode ، MODR/M) و add %al,(%ecx) (كود الآلة: 00 04 21 - Opcode ، MODR/M ، SIB) ، بناء الجملة البديل add %al,(%ecx,%eiz,1) يتم استخدامه بدلاً من ذلك (أو لبناء Intel: add BYTE PTR [ecx+eiz*1],al).

وكما هو موضح في المقالة المرتبطة من قبل سنان ، هذه التعليمات المحددة (lea 0x0(%esi,%eiz,1),%esi) يستخدم مجرد NOP متعدد البايت (يعادل esi = &*esi) بحيث يجب تنفيذ تعليمات واحدة تشبه NOP بدلاً من تعليمات NOP المتعددة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top