سؤال

لدي وظيفة واحدة من الواحد C وهي مجرد return value * pow(1.+rate, -delay); - يقوم بخصم قيمة مستقبلية على القيمة الحالية. الجزء المثير للاهتمام من التفكيك

0x080555b9 :      neg    %eax
0x080555bb :      push   %eax
0x080555bc :      fildl  (%esp)
0x080555bf :      lea    0x4(%esp),%esp
0x080555c3 :      fldl   0xfffffff0(%ebp)
0x080555C6: FLD1 
0x080555c8 :      faddp  %st,%st(1)
0x080555ca :      fxch   %st(1)
0x080555cc :      fstpl  0x8(%esp)
0x080555d0 :      fstpl  (%esp)
0x080555d3 :      call   0x8051ce0 
0x080555d8 :      fmull  0xfffffff8(%ebp)

على الرغم من أن الحزب الواحد من خلال هذه الوظيفة ، يقول GDB (معدل 0.02 ، التأخير هو 2 ؛ يمكنك رؤيتها على المكدس):

(gdb) si
0x080555c6      30        return value * pow(1.+rate, -delay);
(gdb) info float
  R7: Valid   0x4004a6c28f5c28f5c000 +41.68999999999999773      
  R6: Valid   0x4004e15c28f5c28f6000 +56.34000000000000341      
  R5: Valid   0x4004dceb851eb851e800 +55.22999999999999687      
  R4: Valid   0xc0008000000000000000 -2                         
=>R3: Valid   0x3ff9a3d70a3d70a3d800 +0.02000000000000000042    
  R2: Valid   0x4004ff147ae147ae1800 +63.77000000000000313      
  R1: Valid   0x4004e17ae147ae147800 +56.36999999999999744      
  R0: Valid   0x4004efb851eb851eb800 +59.92999999999999972      

Status Word:         0x1861   IE             PE        SF              
                       TOP: 3
Control Word:        0x037f   IM DM ZM OM UM PM
                       PC: Extended Precision (64-bits)
                       RC: Round to nearest
Tag Word:            0x0000
Instruction Pointer: 0x73:0x080555c3
Operand Pointer:     0x7b:0xbff41d78
Opcode:              0xdd45

وبعد fld1:

(gdb) si
0x080555c8      30        return value * pow(1.+rate, -delay);
(gdb) info float
  R7: Valid   0x4004a6c28f5c28f5c000 +41.68999999999999773      
  R6: Valid   0x4004e15c28f5c28f6000 +56.34000000000000341      
  R5: Valid   0x4004dceb851eb851e800 +55.22999999999999687      
  R4: Valid   0xc0008000000000000000 -2                         
  R3: Valid   0x3ff9a3d70a3d70a3d800 +0.02000000000000000042    
=>R2: Special 0xffffc000000000000000 Real Indefinite (QNaN)
  R1: Valid   0x4004e17ae147ae147800 +56.36999999999999744      
  R0: Valid   0x4004efb851eb851eb800 +59.92999999999999972      

Status Word:         0x1261   IE             PE        SF      C1      
                       TOP: 2
Control Word:        0x037f   IM DM ZM OM UM PM
                       PC: Extended Precision (64-bits)
                       RC: Round to nearest
Tag Word:            0x0020
Instruction Pointer: 0x73:0x080555c6
Operand Pointer:     0x7b:0xbff41d78
Opcode:              0xd9e8

بعد هذا ، كل شيء يذهب إلى الجحيم. تتجاوز الأمور بشكل صارخ أو مقومة بأقل من قيمتها ، لذلك حتى لو لم تكن هناك حشرات أخرى في محاولة Freeciv AI الخاصة بي ، فإنها ستختار كل الاستراتيجيات الخاطئة. مثل إرسال الجيش بأكمله إلى القطب الشمالي. (تنهد ، إذا كنت فقط كنت وصلت إلى هذا الحد.)

يجب أن أفتقد شيئًا واضحًا ، أو أعمى عن شيء ما ، لأنني لا أستطيع تصديق ذلك fld1 يجب أن تفشل من أي وقت مضى. حتى أنه يجب أن يفشل فقط بعد حفنة من التمريرات من خلال هذه الوظيفة. في مرور في وقت مبكر ، يتم تحميل FPU بشكل صحيح 1 في ST (0). البايتات في 0x080555C6 تشفر بالتأكيد fld1 - فحص مع x/... في عملية التشغيل.

ما يعطي؟

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

المحلول

مناسبة بشكل ملحوظ. ما لديك هنا هو مكدس فائض.

على وجه التحديد ، لقد فاضت أنت (أو ربما المترجم الخاص بك) مكدس X87. يمكن أن يحمل فقط 8 قيم ، وفي الوقت الذي fld1 تم إصداره ، وهو ممتلئ بالفعل (يشار إليه بكلمة علامة 0000). وهكذا ، و fld1 يفيض المكدس (المشار إليه بواسطة IE, SF, C1) مما يسبب النتيجة التي تراها.

حول سبب حدوث ذلك ، ربما تكون قد استخدمت تعليمات MMX دون استخدام EMMS قبل استخدام تعليمات x87 ، أو أن المترجم الخاص بك يحتوي على خطأ ، أو لديك رمز تجميع في مكان ينتهك ABI من النظام الأساسي الخاص بك (أو مكتبة تستخدمها تنتهك ABI).

نصائح أخرى

يبدو أن لديك فائض مكدس FPU. كلمة علامة FPU هي 0 ، مما يعني أنه يتم استخدام جميع السجلات. يمكنك أيضًا رؤية جميع السجلات المحددة على أنها "صالحة" ، عندما أتوقع أن يكون البعض فارغًا.

لا أعرف لماذا سيحدث هذا. ربما لديك بعض رمز MMX الذي لا يصدر EMMS تعليمات؟ أو ربما بعض التجميع المضمّن الذي لا يزيل المكدس بشكل صحيح؟

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