c++ - কেন জিসিসি এর ফলাফল ব্যবহার না করেই লাইবসির স্কয়ার্ট() কল করে?



gcc assembly (1)

ফলাফলটি গণনা করার জন্য স্কয়ারটি কল করার দরকার নেই; এটি ইতিমধ্যে SQRTSD নির্দেশনা দ্বারা গণনা করা হয়েছে been কোনও errno নেতিবাচক সংখ্যা পাস করার সময় এটি স্ট্যান্ডার্ড অনুযায়ী প্রয়োজনীয় আচরণ তৈরি করতে sqrt কল করে (উদাহরণস্বরূপ, errno সেট করুন এবং / অথবা একটি ভাসমান-পয়েন্ট ব্যতিক্রম উত্থাপন)। PXOR, UCOMISD, এবং JBE নির্দেশাবলী আর্গুমেন্ট 0 এর চেয়ে কম কিনা তা পরীক্ষা করে এবং যদি এটি সত্য না হয় তবে কলটিকে স্কিআরটিতে এড়িয়ে যান।

GCC 6.3 ব্যবহার করে, নিম্নলিখিত সি ++ কোড:

#include <cmath>
#include <iostream>

void norm(double r, double i)
{
    double n = std::sqrt(r * r + i * i);
    std::cout << "norm = " << n;
}

নিম্নলিখিত x86-64 সমাবেশ উত্পন্ন করে:

norm(double, double):
        mulsd   %xmm1, %xmm1
        subq    $24, %rsp
        mulsd   %xmm0, %xmm0
        addsd   %xmm1, %xmm0
        pxor    %xmm1, %xmm1
        ucomisd %xmm0, %xmm1
        sqrtsd  %xmm0, %xmm2
        movsd   %xmm2, 8(%rsp)
        jbe     .L2
        call    sqrt
.L2:
        movl    std::cout, %edi
        movl    $7, %edx
        movl    $.LC1, %esi
        call    std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
        movsd   8(%rsp), %xmm0
        movl    std::cout, %edi
        addq    $24, %rsp
        jmp     std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)

sqrtsd std::sqrt এ কল করার জন্য, জিসিসি প্রথমে এটি sqrtsd ব্যবহার করে sqrtsd স্ট্যাকের মধ্যে সংরক্ষণ করে। যদি এটি প্রবাহিত হয়, তবে এটি libc sqrt ফাংশনটিকে কল করে। তবে এটি xmm0 পরে কখনও সংরক্ষণ করে না এবং xmm0 আগে দ্বিতীয় কল করার আগে এটি স্ট্যাক থেকে মানটি পুনরুদ্ধার করে (কারণ xmm0 operator<< প্রথম কল দিয়ে হারিয়ে গেছে)।

একটি সহজ std::cout << n; এটি আরও সুস্পষ্ট:

subq    $24, %rsp
movsd   %xmm1, 8(%rsp)
call    sqrt
movsd   8(%rsp), %xmm1
movl    std::cout, %edi
addq    $24, %rsp
movapd  %xmm1, %xmm0
jmp     std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)

কেন জিসিসি xmm0 দ্বারা xmm0 মান ব্যবহার করছে না?






x86-64