إخراج جمعية دول مجلس التعاون الخليجي لبرنامج فارغ على X86، Win32
سؤال
أكتب برامج فارغة لإزعاج الجحيم من المبرمجين Stackoverflow، وليس. أنا فقط استكشاف Toolchain جنو.
الآن قد يكون ما يلي عميقا جدا بالنسبة لي، ولكنه في الاستمرار في البرنامج الفارغ الذي بدأته في فحص إخراج مترجم C، والأشياء جنو تستهلك.
gcc version 4.4.0 (TDM-1 mingw32)
test.c:
int main()
{
return 0;
}
GCC -S Test.C.
.file "test.c"
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
call ___main
movl $0, %eax
leave
ret
هل يمكنك شرح ما يحدث هنا؟ هنا جهدي لفهمها. لقد استخدمت as
دليل ودليل X86 ASM المعرفة:
.file "test.c"
هو التوجيه للحصول على اسم الملف المنطقي..def
: وفقا للمستندات "البدء في تحديد معلومات تصحيح الأخطاء للحصول على اسم رمز". وبعد ما هو الرمز (اسم وظيفة / متغير؟) وأي نوع من معلومات التصحيح؟.scl
: مستندات يقول "قد علم فئة التخزين ما إذا كان رمز ثابت أو خارجي". وبعد هل هذا هو نفسه ثابتة و خارجي أنا أعرف من ج؟ وماذا هو "2"؟.type
: يخزن المعلمة "كعمل نوع من إدخال جدول الرمز", ، ليس لدي أي فكرة..endef
: لا مشكلة..text
: الآن هذا هو مشكلة، يبدو أنه شيء يسمى القسم وأنا قرأت أن مكانه للحصول على التعليمات البرمجية، لكن المستندات لم تخبرني كثيرا..globl
"يجعل الرمز مرئيا إلى LD.", ، الدليل واضح تماما على هذا._main:
قد يكون هذا هو عنوان التشغيل (؟) لوظيفتي الرئيسيةpushl_
: دفع طويل (32 بت)، الذي الأماكن EBP على المكدسmovl
: خطوة 32 بت. Pseudo-C:EBP = ESP;
andl
: منطقي و. Pseudo-C:ESP = -16 & ESP
, أنا لا أرى حقا ما هي نقطة هذا.call
: يدفع IP إلى المكدس (لذلك يمكن للإجراء المسمى العثور على طريقه مرة أخرى) ويستمر فيها__main
يكون. (ما هو __main؟)movl
: يجب أن يكون هذا الصفر هو ثابت أعود في نهاية التعليمات البرمجية. تضع MOV هذا الصفر في EAX.leave
: يستعيد كومة بعد تعليمات الدخول (؟). لماذا ا؟ret
: يعود إلى عنوان التعليمات الذي يتم حفظه على المكدس
شكرا لك على مساعدتك!
المحلول
.file "test.c"
أوامر تبدأ مع. هي توجيهات للمجمع. هذا يقول فقط هذا هو "ملف file.c"، يمكن تصدير هذه المعلومات إلى معلومات تصحيح الأخطاء من EXE.
.def ___main؛ .scl 2؛ . Type 32؛ .endef.
تعرف توجيهات .DEF رمز تصحيح الأخطاء. SCL 2 يعني تخزين فئة 2 (فئة التخزين الخارجية). يقول Type 32 إن هذه Sumbol هي وظيفة. سيتم تعريف هذه الأرقام بواسطة تنسيق PE-COFT EXE
___Main هي وظيفة تسمى التي تعتني بإعصار الأحذية التي يحتاجها دول مجلس التعاون الخليجي (سوف تفعل أشياء مثل Run C ++ Inticizers ثابتة وغيرها من التدبير المنزلي اللازم).
.text
يبدأ قسم النص - رمز حياة هنا.
.globll _main.
يحدد رمز _main باسم Global، والذي سيجعله مرئيا إلى الرابط والوحدات الأخرى المرتبطة بها.
.def _main; .scl 2; .type 32; .endef
نفس الشيء مثل _main، يخلق رموز تصحيح الأخطاء تفيد بأن _main وظيفة. هذا يمكن استخدامه من قبل الهياجين.
_رئيسي:
يبدأ ملصق جديد (سوف ينتهي عنوان). إن التوجيه .globlbl أعلاه يجعل هذا العنوان مرئيا للكيانات الأخرى.
pushl %ebp
يحفظ مؤشر الإطار القديم (سجل EBP) على المكدس (حتى يمكن وضعه في مكانه عند انتهاء هذه الوظيفة)
movl %esp, %ebp
ينقل مؤشر المكدس إلى سجل EBP. غالبا ما يسمى EBP مؤشر الإطار، حيث يشير إلى أعلى قيم المكدس داخل "الإطار" الحالي (وظيفة "عادة)، (بالإشارة إلى المتغيرات الموجودة على المكدس عبر EBP يمكن أن تساعد المصاجرين)
أندل $ -16،٪ esp
و ands المكدس مع FFFFFFFF0 الذي يحاذيه بشكل فعال على حدود 16 بايت. الوصول إلى القيم المحاذاة على المكدس أسرع بكثير مما لو كانوا غير إجماليين. كل هذه التعليمات السابقة هي prologue وظيفة قياسية.
call ___main
يستدعي وظيفة ___main التي ستقوم بتهيئة الأشياء التي يحتاجها دول مجلس التعاون الخليجي. سيؤدي المكالمة إلى دفع مؤشر التعليمات الحالية على المكدس والقفز إلى عنوان ___main
movl $0, %eax
نقل 0 إلى سجل EAX، (0 في المقابل 0؛) يتم استخدام سجل EAX لعقد قيم إرجاع وظيفة لاتفاقية الاتصال STDCALL.
غادر
تعليمات الإجازة اختصار إلى حد كبير
movl ebp,esp popl ebp
أي أنها "التراجع" التي تم القيام بها بالأشياء في بداية الوظيفة - استعادة مؤشر الإطار والمكدس إلى حالتها السابقة.
ريد
يعود إلى من يسمى هذه الوظيفة. سوف ينبثق مؤشر التعليمات من المكدس (التي ستوضع فيها إرشادات المكالمات المقابلة هناك) والقفز هناك.
نصائح أخرى
هناك تمرين مشابه للغاية محدد هنا: http://en.wikibooks.org/wiki/x86_assembly/gas_syntax.
لقد اكتشفت معظمها - سأحدث ملاحظات إضافية للتأكيد والإضافات.
__main
هو روتين فرعي في مكتبة جنو القياسية التي تعتني بمختلف تهيئة بدء التشغيل. ليس من الضروري بدقة لبرامج ج ولكن مطلوب فقط في حالة ربط رمز C مع C ++.
_main
هو الروتين الفرعي الرئيسي الخاص بك. كما كلاهما _main
و __main
هي مواقع التعليمات البرمجية لديهم نفس فئة التخزين والنوع. لم أفعل بعد التعاريف .scl
و .type
بعد. قد تحصل على بعض الإضاءة من خلال تحديد عدد قليل من المتغيرات العالمية.
تقوم التعليمات الثلاثة الأولى بإعداد إطار مكدس وهو مصطلح تقني لتخزين العمل من المتغيرات المحلية والمؤقتة بالنسبة للجزء الأكبر. دفع ebp
يحفظ قاعدة إطار مكدس المتصل. وضع esp
إلى ebp
يضبط قاعدة إطار المكدس لدينا. ال andl
قم بمحاذاة إطار المكدس إلى حدود 16 بايت فقط في حالة حدوث أي متغيرات محلية على المكدس تتطلب محاذاة 16 بايت (ل X86 لتعليمات SIMD تتطلب المحاذاة، ولكن محاذاة تسرع أنواع عادية مثل int
رمل float
س.
في هذه المرحلة كنت تتوقع عادة esp
للحصول على نقل في الذاكرة لتخصيص مساحة مكدس للمتغيرات المحلية. لك main
ليس لديه أي دول مجلس التعاون الخليجي لا تهتم.
دعوة إلى __main
هو خاص إلى نقطة الدخول الرئيسية ولن يظهر عادة في الروتين الفرعي.
الباقي يذهب كما remmised. يسجل eax
هو المكان المناسب لوضع رموز الإرجاع الصحيحة في المواصفات الثنائية. leave
يطل على إطار المكدس و ret
يعود إلى المتصل. في هذه الحالة، المتصل هو وقت تشغيل C منخفض المستوى الذي سيفعل سحر إضافي (مثل الاتصال atexit()
وظائف، اضبط رمز الخروج لهذه العملية واسأل نظام التشغيل إنهاء العملية.
حول ذاك أندل $ -16،٪ esp
- 32 بت: -16 في العشرية يساوي 0xFFFFFF0 في التمثيل السداسي عشري
- 64 بت: -16 في العشرية يساوي 0xFFFFFFFFFFF0 في التمثيل السداسي عشري
لذلك ستخفي الجزء الأخير من 4 بت من ESP (BTW: 2 ** 4 يساوي 16) وسوف يحتفظ بجميع البتات الأخرى (بغض النظر عما إذا كان النظام المستهدف هو 32 أو 64 بت).
كذلك إلى andl $-16,%esp
, ، هذا يعمل لأن تحديد البتات المنخفضة إلى الصفر سوف تضبط دائما %esp
أسفل في القيمة، وينتف على المكدس على x86.
ليس لدي كل إجابات ولكن يمكنني شرح ما أعرفه.
ebp
يتم استخدامها من قبل الوظيفة لتخزين الحالة الأولية esp
أثناء تدفقها، إشارة إلى أين تنتقل الحجج إلى الوظيفة وأين هي المتغيرات المحلية الخاصة بها. أول شيء يفعله الوظيفة هو حفظ حالة المعطى ebp
عمل pushl %ebp
, ، من الضروري الوظيفة التي تجعل المكالمة، ومن استبدالها بموقف المكدس الحالي esp
عمل movl %esp, %ebp
. وبعد تصفية آخر 4 بت من ebp
في هذه المرحلة هو محددة دول مجلس التعاون الخليجي، لا أعرف لماذا هذا التحويل البرمجي يفعل ذلك. سيعمل دون القيام بذلك. الآن أخيرا نذهب إلى العمل، call ___main
, من هو __main؟ أنا لا أعرف إما ... ربما أكثر إجراءات محددة من دول مجلس التعاون الخليجي، وأخيرا الشيء الوحيد الخاص بك الرئيسي ()، تعيين قيمة الإرجاع كما 0 مع movl $0, %eax
و leave
وهو نفسه كما تفعل movl %ebp, %esp; popl %ebp
لاستعادة ebp
الدولة، إذن ret
لانهاء. ret
الملوثات العضوية الثابتة eip
ومواصلة تدفق الخيط من تلك النقطة، أينما كان (كما هو الرئيسي ()، فإن هذا الرعيد يؤدي إلى بعض إجراءات النواة التي تعالج نهاية البرنامج).
معظم كل شيء يدور حول إدارة المكدس. كتبت برنامج تعليمي مفصل حول كيفية استخدام المكدس منذ بعض الوقت، سيكون من المفيد شرح سبب صنع كل هذه الأشياء. لكن في البرتغالية ...