لماذا هذا البرنامج البسيط يخرج الكثير من الشخصيات؟

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

  •  02-10-2019
  •  | 
  •  

سؤال

هنا أنا قصيرة برنامج التجميع:

; This code has been generated by the 7Basic
; compiler <http://launchpad.net/7basic>

extern printf

; Initialized data

      SECTION .data
f_0 dd 5.5
printf_f: db "%f",10,0

      SECTION .text

; Code

global main
  main:
push ebp
mov ebp,esp

push dword [f_0]
push printf_f
call printf
add esp,8

mov esp,ebp
pop ebp
mov eax,0
ret

ما هو البرنامج مفترض للقيام هو الطباعة 5.5 ، لكنها تطبع:

-4101885043414705786563701568963176764603483495211119243453355953219830430011006780068899468997203661787555969981250050126586203424320244681571103387315766489883301796219461838644670607029711305942610787622864198879363376953745160639821663444829839767678538571371627347101810056161000273217639447052410683392.000000

ما الذي أفعله خطأ على الأرض؟ الرمز يدفع الوسيطتين إلى printf() ثم تسميها. لا شيء معقد.


تحديث: كنت من السابق لأوانه بعض الشيء في التفكير في أنني قد أصلحت هذا. لقد قمت بتحديث الرمز.

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

المحلول

التعليمات push f_0 يدفع عنوان F_0 على المكدس ، وليس 5.5 في الذاكرة هناك ، وبالتالي فإن روتين printf سيأخذ العنوان ، بالإضافة إلى EBP المحفوظ (البايتات الأربعة التالية على المكدس) وتفسير البتات على أنها مزدوجة وطباعته. تبين أن هذا عدد كبير جدًا ، كما ترى.

تحتاج إلى تحميل 8 بايت من f_0 ودفع هؤلاء. شيء مثل

move eax, f_0
push dword ptr [eax+4]
push dword ptr [eax]

تعديل

تحتاج إلى دفع 8 بايت لأن قيم FP64 هي 8 بايت. FP64 هو كل ما يعرفه PrintF كيفية الطباعة - في الواقع FP64 هو كل ما يعرفه C كيفية المرور إلى الوظائف أو العمل. لا يمكن تحميل قيمة FP32 إلا من الذاكرة وتخزينها ، ولكن يتم تحويلها ضمنيًا إلى FP64 (أو أكبر) قبل تشغيلها. إذا كنت ترغب في تحميل قيمة FP32 ، وتحويلها FP64 ، ودفعها على المكدس ، يمكنك استخدامها

fld dword ptr [f_0]
sub esp, 8
fstp qword ptr [esp]

هذا في الواقع يقوم بتحميل قيمة FP32 ويحولها إلى FP80 (التنسيق الداخلي لـ X87) ، ثم يقوم بتحويل قيمة FP80 إلى FP64 وتخزينها على المكدس.

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