دول مجلس التعاون الخليجي مضمنة المجمع خلط سجل أحجام (x86)

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

  •  02-07-2019
  •  | 
  •  

سؤال

لا أحد يعرف كيف يمكن التخلص من التالية المجمع التحذير ؟

رمز إلى x86 ، 32 بت:

int test (int x)
{
  int y;
  // do a bit-rotate by 8 on the lower word. leave upper word intact.
  asm ("rorw $8, %0\n\t": "=q"(y) :"0"(x));
  return y;
}

إذا كنت تجميع أحصل على ما يلي (صحيح جدا) تحذير:

Warning: using `%ax' instead of `%eax' due to `w' suffix

ما أبحث عنه هو طريقة لمعرفة مترجم/المجمع الذي أريد الوصول إلى أقل من 16 بت الفرعية التسجيل من %0.الوصول إلى بايت الفرعية السجلات (في هذه الحالة آل و آه) سيكون من الجميل أن تعرف.

لقد اختارت "س" التعديل ، حتى المترجم اضطر إلى استخدام EAX, EBX, ECX أو EDX.لقد حرصت على المترجم أن تختار سجل فرعية من السجلات.

وأنا أعلم أنني يمكن أن يجبر asm-إلى سجل محدد (و الفرعية سجلات), ولكن أنا أريد أن أترك سجل توزيع العمل تصل إلى مترجم.

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

المحلول

يمكنك استخدام %w0 إذا كنت أتذكر الحق.لقد اختبرت ذلك أيضا.:-)

int
test(int x)
{
    int y;
    asm ("rorw $8, %w0" : "=q" (y) : "0" (x));
    return y;
}

تحرير:ردا على العملية ، نعم ، يمكنك القيام بما يلي أيضا:

int
test(int x)
{
    int y;
    asm ("xchg %b0, %h0" : "=Q" (y) : "0" (x));
    return y;
}

في الوقت الحاضر, المكان الوحيد (أعلم) انها موثقة في gcc/config/i386/i386.md, وليس في أي من الوثائق القياسية.

نصائح أخرى

منذ فترة طويلة, ولكن سوف تحتاج على الأرجح هذا من أجل مستقبل بلدي المرجعية...

إضافة إلى كريس بخير الإجابة يقول المفتاح باستخدام معدل بين '%' وعدد من انتاج المعامل.على سبيل المثال ، "MOV %1, %0" قد تصبح "MOV %q1, %w0".

لم أستطع العثور على أي شيء في القيود.md, ولكن /الخليج/config/i386/i386.ج كان هذا يمكن أن تكون مفيدة التعليق في المصدر print_reg():

/* Print the name of register X to FILE based on its machine mode and number.
   If CODE is 'w', pretend the mode is HImode.
   If CODE is 'b', pretend the mode is QImode.
   If CODE is 'k', pretend the mode is SImode.
   If CODE is 'q', pretend the mode is DImode.
   If CODE is 'x', pretend the mode is V4SFmode.
   If CODE is 't', pretend the mode is V8SFmode.
   If CODE is 'h', pretend the reg is the 'high' byte register.
   If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
   If CODE is 'd', duplicate the operand for AVX instruction.
 */

التعليق أدناه ix86_print_operand() نقدم مثالا على ذلك:

ب-طباعة QImode اسم السجل إلى المعامل.

%b0 طباعة %al إذا المعاملات[0] هو ريج 0.

عدد قليل من الخيارات أكثر فائدة مدرجة في إطار إخراج القالب من دول مجلس التعاون الخليجي الداخلية الوثائق:

'%cdigit' يمكن استخدامها بديلا المعامل التي هو ثابت القيمة دون الجملة التي عادة يشير فوري المعامل.

'%ndigit' مثل '%cdigit' إلا أن قيمة ثابت انتفى قبل الطباعة.

'%adigit' يمكن استخدامها بديلا المعامل كما لو كانت الذاكرة المرجعية الفعلية المعامل يعامل العنوان.قد يكون هذا مفيدة عند إخراج "حمل عنوان" تعليم, لأنه في كثير من الأحيان المجمع اللغوي لهذه التعليمات يتطلب منك كتابة المعامل كما لو كانت الذاكرة المرجعية.

'%ldigit' يستخدم بديلا label_ref في القفز التعليمات.

'%=' إخراج عدد منها هي فريدة من نوعها إلى كل التعليمات في تجميع كامل.هذا هو مفيدة لصنع المحلية المسميات المشار إليها أكثر من مرة في قالب واحد أن يولد متعددة تعليمات المجمع.

إن '%c2'بناء يسمح واحدة تهيئة بشكل صحيح وهو ليا تعليمات باستخدام الإزاحة:

#define ASM_LEA_ADD_BYTES(ptr, bytes)                            \
    __asm volatile("lea %c1(%0), %0" :                           \
                   /* reads/writes %0 */  "+r" (ptr) :           \
                   /* reads */ "i" (bytes));

ملاحظة حاسمة ولكن أحيانا موثقة 'ج' في '%c1'.هذا الماكرو هو ما يعادل

ptr = (char *)ptr + bytes

ولكن من دون الاستفادة من المعتاد صحيح الحسابية تنفيذ الموانئ.

تحرير لإضافة:

مما يجعل المكالمات المباشرة في x64 يمكن أن يكون صعبا ، كما أنه يتطلب آخر غير الشرعيين التعديل:'%P0'(والتي يبدو أن يكون على الموافقة المسبقة عن علم)

#define ASM_CALL_FUNC(func)                                         \
    __asm volatile("call %P0") :                                    \
              /* no writes */ :                                     \
              /* reads %0 */ "i" (func))                           

أقل القضية 'p' معدل يبدو أيضا أن تعمل نفس الشيء في دول مجلس التعاون الخليجي ، على الرغم من أن فقط رأس المال 'P' معترف بها من قبل المحكمة الجنائية الدولية.مزيد من التفاصيل هي على الأرجح المتاحة في /الخليج/config/i386/i386.ج.البحث عن "'ع'".

بينما أنا أفكر في ذلك ...يجب أن تحل محل "س" القيد بحرف "س" القيد في كريس الحل الثاني:

int
test(int x)
{
    int y;
    asm ("xchg %b0, %h0" : "=Q" (y) : "0" (x));
    return y;
}

"س" و "س" هي مختلفة قليلا في وضع 64 بت, حيث يمكنك الحصول على أقل بايت لكل عدد صحيح السجلات (ax, bx, cx, dx, si, di, sp, bp, r8-r15).ولكن يمكنك فقط الحصول على ثاني أدنى بايت (مثلا ، آه) الأربعة الأصلية 386 السجلات (ax, bx, cx, dx).

على ما يبدو هناك الحيل أن تفعل هذا...لكنها قد لا تكون فعالة جدا.32 بت x86 معالجات عموما بطيئة في التلاعب 16 بت من البيانات في سجلات للأغراض العامة.يجب أن المعيار هو إذا كان الأداء هو المهم.

إلا إذا كان هذا هو (أ) الأداء الحرجة و (ب) يثبت أن تكون أسرع بكثير ، أنا من شأنه أن ينقذ نفسي بعض الصيانة المتاعب فقط تفعل ذلك في ج:

uint32_t y, hi=(x&~0xffff), lo=(x&0xffff);
y = hi + (((lo >> 8) + (lo << 8))&0xffff);

مع دول مجلس التعاون الخليجي 4.2 و O2 هذا يحصل الأمثل وصولا إلى ستة تعليمات...

مسكتك.وكذلك إذا البدائية الروتينية التي ستكون إعادة استخدام أكثر و أكثر, أنا لا أختلف مع ذلك...السجل تسمية الحيلة التي أشار كريس هو لطيف واحد من أنني سوف تضطر إلى تذكر.

سيكون من الجميل لو جعلها في مستوى دول مجلس التعاون الخليجي مستندات جدا!

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