تحديد البايتات في التجميع المضمّن في مجلس التعاون الخليجي في Dev-C ++ (. ASCII في بناء جملة AT&T على Windows)

StackOverflow https://stackoverflow.com/questions/3712062

سؤال

الكود أدناه هو مجرد عرض مربع رسالة على الشاشة.
العناوين متشددين لتسهيل:

int main ()
{
    asm("xorl %eax, %eax        \n"
        "xorl %ebx, %ebx        \n"
        "xorl %ecx, %ecx        \n"
        "xorl %edx, %edx        \n"
        "pushl %ecx             \n" //$0x0
        "pushl $0x20206c6c      \n" //"  ll"
        "pushl $0x642e3233      \n" //"d.23"
        "pushl $0x72657375      \n" //"resu"
        "movl %esp, %ecx        \n" //store "user32.dll" address in %ecx
        "movl $0x7c801d7b, %ebx \n" //store address of LoadLibraryA in %ebx
        "pushl %ecx             \n"
        "call *%ebx             \n"
        "movl $0xef30675e, %ecx \n"
        "addl $0x11111111, %ecx \n"
        "pushl %ecx             \n"
        "pushl $0x42656761      \n"
        "pushl $0x7373654d      \n"
        "movl %esp, %ecx        \n"
        "pushl %ecx             \n"
        "pushl %eax             \n"
        "movl $0x7c80ae40, %ebx \n"
        "call *%ebx             \n"
        "movl %esp, %ecx        \n"
        "xorl %edx, %edx        \n"
        "pushl %edx             \n"
        "pushl %ecx             \n"
        "pushl %ecx             \n"
        "pushl %edx             \n"
        "call *%eax             \n"
        "xorl %eax, %eax        \n"
        "pushl %eax             \n"
        "movl $0x7c81cb12, %eax \n"
        "call *%eax             \n"
    );
}

(لم أعلق على كل الرمز لأن سؤالي لا يتعلق حقًا بالرمز)

سؤالي هو: هل هناك طريقة لكتابة السلسلة "user32.dll" في التجميع المضمّن دون الدفع يدويًا إلى المكدس؟ أعني مثل هذا في Nasm: db 'Hello'

أعلم أنه في بناء الجملة AT&T يمكنني القيام به .ascii 'Hello' أو .string 'Hello' ولكن ماذا عن في مجلس التعاون الخليجي المضمّن؟

يرجى ملاحظة أنني أستخدم Dev-C ++ على Windows XP SP3

شكرًا!

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

المحلول

نعم ، من خلال الاستفادة من توجيهات التجميع داخل المجمع المضمن. الخدعة في وضع السلسلة في المكان الصحيح (قسم البيانات) ، والتي يمكنك القيام بها عن طريق التبديل باستخدام .section .data, ثم العودة مرة أخرى مع .section .text.

يجب أن تعطي البيانات تسمية حتى تتمكن من الرجوع إليها ؛ أوصي باستخدام بناء جملة الملصقات المحلي هنا (حيث تكون التسمية رقمًا ، على سبيل المثال 1:, ، وأنت تشير إليها على أنها إما 1b لأول 1: تسمية للخلف ، أو 1f لأول 1: تسمية إلى الأمام - انظر وثائق تجميع GNU لمزيد من التفاصيل).

مثله:

int main(void)
{
  asm(".section .data      \n"
      "1: .asciz \"Hello\" \n"
      ".section .text      \n"
      "pushl $1b           \n"
      "call _puts          \n"
      "add $4, %esp        \n"
     );
  return 0;
}

ليس لدي نظام Windows مفيد لاختبار ذلك ، لكنه يجمع بشكل جيد ويبدو أنه يجب أن يفعل الشيء الصحيح باستخدام mingw cross-compiler على Linux (أعتقد أن Dev-C ++ يعتمد على mingw).

ملاحظة: تنطبق هذه التقنية بشكل عام عند استخدام مجموعة أدوات GNU. إذا كنت تقوم ببناء ثنائيات Elf (مثل Linux الأصلي) ، فهناك طريقة أكثر إمتاعًا للعودة إلى قسم النص ، والتي تتمثل في الاستخدام .previous, ، وهو ما يعني "مهما كان القسم قبل السابق .section كان ". (المثال أعلاه يعمل على Linux إذا قمت بتغيير _puts إلى puts لحساب اتفاقيات البادئة المختلفة.)

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