স্ট্যাক মেমরিটি কেন ব্যবহার না করে বরাদ্দ করা হয়?


14

নিম্নলিখিত উদাহরণ বিবেচনা করুন:

struct vector {
    int  size() const;
    bool empty() const;
};

bool vector::empty() const
{
    return size() == 0;
}

এর জন্য উত্পন্ন সমাবেশ কোড vector::empty(অনুকূলকরণ সহ ঝনঝন করে):

push    rax
call    vector::size() const
test    eax, eax
sete    al
pop     rcx
ret

কেন এটি স্ট্যাক স্পেস বরাদ্দ করে? এটি মোটেই ব্যবহৃত হয় না। pushএবং popবাদ দেওয়া যেতে পারে। এমএসভিসি এবং জিসিসির অনুকূল বিল্ডগুলিও এই ফাংশনের জন্য স্ট্যাক স্পেস ব্যবহার করে ( গডবোল্টে দেখুন ), সুতরাং অবশ্যই একটি কারণ থাকতে হবে।


7
আপনি কি অন্তর্নিহিত thisপ্যারামিটারের জন্য অ্যাকাউন্ট করেছিলেন ?
dan04

1
@ Bob__: না কেন আমার উচিত? vector::size()উদাহরণ হিসাবে সংজ্ঞায়িত করা হয় না যে এটি ইনলাইনড নয়।
ডাঃ গুট

1
সুতরাং, একটি সংকলক এটি জানে না এমন কোনও বিষয়টিকে কীভাবে অনুকূল করতে পারে?
বব__

1
@ Bob__: আমি মনে করি, বাস্তবায়ন জানার vector::size()জন্য স্ট্যাক ফ্রেম বরাদ্দ বা বরাদ্দ না প্রাসঙ্গিক vector::empty()। ইন empty()এটা ঠিক বলা হয়, যাই হোক না কেন।
ডাঃ গুট

1
ঠিক আছে, আপনি এমন একটি ফাংশন কল করছেন যা কিছু ফেরত দেয় , এর জন্য আপনার স্থান প্রয়োজন (যদি আপনি আরও ভাল না জানেন)।
বব__

উত্তর:


11

এটি স্ট্যাকের স্থান বরাদ্দ করে, তাই স্ট্যাকটি 16-বাইট প্রান্তিককরণ করা হয়। এটি প্রয়োজন, কারণ ফেরতের ঠিকানাতে 8 বাইট লাগে, তাই স্ট্যাকটি 16-বাইট সারিবদ্ধ রাখতে অতিরিক্ত 8-বাইট স্থান প্রয়োজন।

স্ট্যাক ফ্রেমের সারিবদ্ধতা কিছু সংকলকগুলির জন্য কমান্ড লাইন আর্গুমেন্টের সাথে কনফিগার করা যেতে পারে।

  • এমএসভিসি : ডকুমেন্টেশন বলছে যে স্ট্যাকটি সর্বদা 16 বাইট সারিবদ্ধ থাকে। কোনও কমান্ড লাইনের যুক্তি এটি পরিবর্তন করতে পারে না। গডবোল্ট উদাহরণ দেখায় যে rspফাংশনের শুরুতে 40 বাইট বিয়োগ করা হয় যার অর্থ অন্য কোনও কিছু এটির উপরও প্রভাব ফেলে।
  • ঝনঝন : -mstack-alignmentবিকল্প স্ট্যাক প্রান্তিককরণ নির্দিষ্ট করে। দেখে মনে হচ্ছে, ডিফল্টটি 16, যদিও নথিভুক্ত করা হয়নি। আপনি যদি এটি 8 তে সেট করেন তবে উত্পন্ন সমাবেশ কোড থেকে স্ট্যাক বরাদ্দ ( pushএবং pop) অদৃশ্য হয়ে যাবে।
  • জিসিসি : -mpreferred-stack-boundaryবিকল্পটি স্ট্যাক প্রান্তিককরণ নির্দিষ্ট করে। প্রদত্ত মান যদি N হয় তবে এর অর্থ অ্যালাইনমেন্টের 2 ^ N বাইট। ডিফল্ট মান 4, যার অর্থ 16 বাইট। যদি আপনি এটি 3 (যেমন 8 বাইট) সেট করেন তবে উত্পন্ন সমাবেশ কোড থেকে স্ট্যাক বরাদ্দ ( subএবং addজন্য rsp) অদৃশ্য হয়ে যাবে।

উপর পরীক্ষা করে দেখুন godbolt


এই কারণেই সি ++ গুরু, বিশেষজ্ঞরা সর্বদা সতর্ক করে
আসছেন

@ গেজা: আপনাকে ধন্যবাদ আমি অন্য দুটি সংকলকের জন্য কিছু গবেষণা করেছি, এবং এটি আপনার উত্তরে লিখেছি। আপনার কি এটা পছন্দ হয়েছে?
ডাঃ গুট

1
@ ডাঃ গুট: ধন্যবাদ, আপনি উত্তরটি আরও ভাল এবং সম্পূর্ণ করেছেন। দ্রষ্টব্য, এই স্ট্যাক প্রান্তিককরণটি সাধারণত সিস্টেমের জন্য এবিআইতে নথিভুক্ত হয় (উদাহরণস্বরূপ, কিছু সিস্টেমের জন্য, এখানে নথিগুলি রয়েছে: github.com/hjl-tools/x86-psABI/wiki/X86-psABI )।
গেজা

@ গেজা: আপনাকে ধন্যবাদ
ডাঃ গুট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.