বেশিরভাগ আধুনিক সিস্টেমে স্ট্যাক বৃদ্ধির দিকনির্দেশনা কী?


102

আমি সি তে কিছু প্রশিক্ষণ উপকরণ প্রস্তুত করছি এবং আমি চাই আমার উদাহরণগুলি সাধারণ স্ট্যাকের মডেলের সাথে মানিয়ে নিতে।

লিনাক্স, উইন্ডোজ, ম্যাক ওএসএক্স (পিপিসি এবং এক্স 86), সোলারিস এবং সর্বাধিক সাম্প্রতিক ইউনিক্সগুলিতে কোন সি স্ট্যাক বৃদ্ধি পাচ্ছে?


3
একজন কেন নীচের দিকে সংস্করণ: stackoverflow.com/questions/2035568/...
সিরো Santilli郝海东冠状病六四事件法轮功

উত্তর:


147

স্ট্যাক বৃদ্ধি সাধারণত অপারেটিং সিস্টেমের উপর নির্ভর করে না, তবে প্রসেসরের উপর এটি চলছে। উদাহরণস্বরূপ, সোলারিস x86 এবং SPARC এ চলে। ম্যাক ওএসএক্স (যেমন আপনি উল্লেখ করেছেন) পিপিসি এবং x86 এ চলে। লিনাক্স আমার বড় হিনকিন 'সিস্টেম z থেকে শুরু করে একটি ছোট্ট কব্জি ঘড়ি পর্যন্ত কাজ করে ।

সিপিইউ যদি কোনও ধরণের পছন্দ সরবরাহ করে তবে ওএস দ্বারা ব্যবহৃত এবিআই / কলিং কনভেনশন আপনার কোডটি অন্যের কোডকে কল করতে চাইলে আপনাকে কোন পছন্দ করতে হবে তা নির্দিষ্ট করে।

প্রসেসর এবং তাদের দিকনির্দেশ:

  • x86: নিচে।
  • স্পার্ক: নির্বাচনযোগ্য। স্ট্যান্ডার্ড এবিআই ডাউন ব্যবহার করে।
  • পিপিসি: নিচে, আমি মনে করি।
  • সিস্টেম জেড: একটি লিঙ্কযুক্ত তালিকায়, আমি আপনাকে বাচ্চা করব না (তবে এখনও নিচে, কমপক্ষে zLinux এর জন্য)।
  • এআরএম: নির্বাচনযোগ্য, তবে থাম্ব 2-তে কেবল ডাউনের জন্য কমপ্যাক্ট এনকোডিং রয়েছে (এলডিএমআইএ = ইনক্রিমেন্ট পরে, এসটিএমডিবি = আগে হ্রাস)।
  • 6502: ডাউন (তবে কেবল 256 বাইট)
  • আরসিএ 1802 এ: যেভাবেই আপনি চান এসসিআরটি বাস্তবায়নের সাপেক্ষে।
  • PDP11: নিচে।
  • 8051: আপ।

শেষ কয়েকটির উপরে আমার বয়স দেখানো হচ্ছে, 1802 হ'ল চিপটি প্রারম্ভিক শাটলগুলি নিয়ন্ত্রণ করার জন্য ব্যবহৃত হত (অনুভূত হয় যে দরজাগুলি উন্মুক্ত ছিল কিনা, আমি সন্দেহ করি, এটির প্রসেসিং পাওয়ারের ভিত্তিতে :-) এবং আমার দ্বিতীয় কম্পিউটার, COMX-35 ( আমার জেডএক্স 80 অনুসরণ করে )।

PDP11 থেকে উত্পন্ন বিশদ বিবরণ এখানে থেকে 8051 বিস্তারিত এখানে

স্পার্ক আর্কিটেকচারটিতে একটি স্লাইডিং উইন্ডো রেজিস্ট্রার মডেল ব্যবহার করা হয়। স্থাপত্যগতভাবে দৃশ্যমান বিবরণগুলির মধ্যে রেজিস্টার-উইন্ডোগুলির একটি বিজ্ঞপ্তি বাফারও অন্তর্ভুক্ত রয়েছে যা বৈধ এবং অভ্যন্তরীণভাবে ক্যাশে থাকে, যখন ফাঁদগুলি ওভার / প্রবাহিত হয়। বিশদ জন্য এখানে দেখুন । যেমন SPARCv8 ম্যানুয়ালটি ব্যাখ্যা করে , সংরক্ষণ এবং পুনরুদ্ধার নির্দেশাবলী ADD নির্দেশাবলী প্লাস্টিক -উইন্ডো ঘোরানোর মতো। স্বাভাবিক নেতিবাচক পরিবর্তে ইতিবাচক ধ্রুবক ব্যবহার করা একটি upর্ধ্বগামী বর্ধিত স্ট্যাক দেয়।

পূর্বোক্ত এসসিআরটি কৌশলটি অন্যটি হ'ল - 1802 এসসিআরটি (স্ট্যান্ডার্ড কল এবং রিটার্ন কৌশল) এর জন্য 16 বা বিট রেজিস্ট্রার ব্যবহার করেছে বা এটি 16 টি ব্যবহার করেছে। একটি প্রোগ্রামের কাউন্টার ছিল, আপনি SEP Rnনির্দেশের সাথে পিসি হিসাবে যে কোনও নিবন্ধক ব্যবহার করতে পারেন । একটি ছিল স্ট্যাক পয়েন্টার এবং দু'টি সর্বদা এসসিআরটি কোড ঠিকানার দিকে নির্দেশ করার জন্য সেট করা হয়েছিল, একটি কল করার জন্য, একটি ফেরতের জন্য। কোনও রেজিস্টারকে বিশেষভাবে চিকিত্সা করা হয়নি। মনে রাখবেন এই বিবরণগুলি মেমরি থেকে এসেছে, সেগুলি পুরোপুরি সঠিক হতে পারে না।

উদাহরণস্বরূপ, যদি আর 3 পিসি হয়, আর 4 এসসিআরটি কল ঠিকানা ছিল, আর 5 হ'ল এসসিআরটি রিটার্ন ঠিকানা এবং আর 2 ছিল "স্ট্যাক" (এটি সফ্টওয়্যারটিতে প্রয়োগিত হিসাবে উদ্ধৃতিগুলি), SEP R4R4 কে পিসি হিসাবে সেট করবে এবং এসসিআরটি চালানো শুরু করবে কল কোড

এটা তোলে তারপর, R2 হলো "স্ট্যাকের" (আমি মনে করি R6 টেম্প সঞ্চয় করার জন্য ব্যবহার করা হয়েছিল) এ R3 সংরক্ষণ করবে এটি আপ সামঞ্জস্য বা ডাউন, R3 নিম্নলিখিত দুটি বাইট দখল, তাদের লোড মধ্যে R3, তারপর না SEP R3এবং নতুন ঠিকানায় চলমান হতে।

ফিরে আসার জন্য, এটি SEP R5যা পুরানো ঠিকানাটি আর 2 স্ট্যাকের বাইরে টেনে তুলবে, এতে দুটি যুক্ত করুন (কলের ঠিকানা বাইটগুলি এড়িয়ে যেতে), এটি R3 এ লোড করুন এবং SEP R3পূর্ববর্তী কোডটি চালানো শুরু করবেন।

আপনার 6502/6809 / z80 স্ট্যাক-ভিত্তিক কোডের পরে প্রথমে আপনার মাথাটি গুটিয়ে ফেলা খুব কঠিন তবে প্রাচীরের ধারে-বিপরীতমুখী উপায়টিতে এখনও দুর্দান্ত leg এছাড়াও চিপের বড় বিক্রয় বৈশিষ্ট্যগুলির মধ্যে একটি ছিল 16 16-বিট রেজিস্টারগুলির একটি সম্পূর্ণ স্যুট, যদিও আপনি তাত্ক্ষণিকভাবে তাদের মধ্যে 7 টি হারিয়ে ফেলেছেন (এসসিআরটি-এর জন্য 5 জন, ডিএমএর জন্য দুটি এবং স্মৃতি থেকে বিঘ্নিত)। আহ, বাস্তবতার ওপরে বিপণনের বিজয় :-)

সিস্টেম জেডটি আসলে একইরকম, কল / রিটার্নের জন্য এর আর 14 এবং আর 15 রেজিস্টার ব্যবহার করে।


3
তালিকায় যুক্ত করার জন্য, এআরএম উভয় দিকেই বাড়তে পারে তবে নির্দিষ্ট সিলিকন প্রয়োগের মাধ্যমে একটি বা অন্যটিতে সেট করা যেতে পারে (বা সফ্টওয়্যার দ্বারা নির্বাচনযোগ্য রেখে দেওয়া যেতে পারে)। আমি কয়টি লোকের সাথেই কাজ করেছি তারা বরাবরই গ্রো-ডাউন মোডে ছিল।
মাইকেল বারার

1
আমি এ পর্যন্ত এআরএম জগতের সামান্য কিছুটা দেখেছি (এআরএম 7 ডিটিএমআই) স্ট্যাকটি সম্পূর্ণরূপে সফ্টওয়্যারটিতে পরিচালিত হয়। রিটার্ন ঠিকানাগুলি কোনও রেজিস্টারে সংরক্ষণ করা হয় যা প্রয়োজনে সফ্টওয়্যার দ্বারা সংরক্ষণ করা হয় এবং প্রাক-পোস্ট-ইনক্রিমেন্ট / হ্রাস নির্দেশাবলী এটিকে এবং অন্যান্য জিনিসগুলি স্ট্যাকের উভয় দিকে রাখার অনুমতি দেয়।
স্টার ব্লু

1
একটি এইচপিপিএ, স্ট্যাক বড় হয়েছে! যুক্তিসঙ্গতভাবে আধুনিক স্থাপত্যগুলির মধ্যে মোটামুটি বিরল।
টিএমএল


1
আপনার বোঝার জন্য ধন্যবাদ @ প্যাক্সিডিয়াবলো কখনও কখনও আপনি যখন এ জাতীয় মন্তব্য করেন তখন লোকে এটিকে ব্যক্তিগত প্রতিক্রিয়া হিসাবে গ্রহণ করে, বিশেষত যখন এটি কোনও বয়স্ক। আমি কেবল জানি একটি পার্থক্য আছে কারণ আমি অতীতেও একই ভুল করেছি। যত্ন নিবেন.
কাসাডিরোবিসন

23

সি ++ এ (সি এর সাথে অভিযোজিত) স্ট্যাক সি সি :

static int
find_stack_direction ()
{
    static char *addr = 0;
    auto char dummy;
    if (addr == 0)
    {
        addr = &dummy;
        return find_stack_direction ();
    }
    else
    {
        return ((&dummy > addr) ? 1 : -1);
    }
}

14
বাহ, আমি "অটো" কীওয়ার্ডটি দেখেছি অনেক দিন হয়েছে।
প্যাক্সিডিয়াবলো

9
(& ডামি> সংযোজক) অপরিজ্ঞাত। দুটি পয়েন্টারকে রিলেশনাল অপারেটরের খাওয়ানোর ফলাফল কেবল তখনই সংজ্ঞায়িত করা হয় যদি দুটি পয়েন্টার একই অ্যারে বা কাঠামোর মধ্যে নির্দেশ করে।
সিগজুইস

2
আপনার নিজের স্ট্যাকের বিন্যাসটি খতিয়ে দেখার চেষ্টা করা হচ্ছে - এমন কিছু যা সি / সি ++ একেবারেই নির্দিষ্ট করে না - এটি "অপ্রতুলযোগ্য", তাই আমি এটি সম্পর্কে সত্যই যত্ন নেব না। দেখে মনে হচ্ছে এই ফাংশনটি কেবল একবারে সঠিকভাবে কাজ করবে।
প্রচারিত

9
এটির জন্য কোনও ব্যবহার করার দরকার নেই static। পরিবর্তে আপনি ঠিকানাটি পুনরাবৃত্তির কল হিসাবে যুক্তি হিসাবে পাস করতে পারেন।
আর .. গীটহাব থামিয়ে দিন ICE

5
এছাড়াও, একটি ব্যবহার করে staticআপনি যদি একাধিক বার কল করেন তবে পরবর্তী কলগুলি ব্যর্থ হতে পারে ...
ক্রিস ডড

7

পুরানো সিস্টেমে নীচে বাড়ার সুবিধা হ'ল স্ট্যাকটি সাধারণত মেমরির শীর্ষে ছিল। প্রোগ্রামগুলি সাধারণত নিচ থেকে শুরু হয়ে থাকে মেমরির এই ধরণের মেমরি পরিচালনার ফলে স্ট্যাকের নীচে কোথাও বোধগম্যতা পরিমাপ করার এবং রাখার প্রয়োজনীয়তা হ্রাস পায়।


3
একটি 'সুবিধা' নয়, একটি টোটোলজি সত্যই।
লার্নের মারকুইস

1
টোটোলজি নয়। কথাটি হ'ল দুটি ক্রমবর্ধমান মেমরি অঞ্চল হস্তক্ষেপ করছে না (যদি না যাই হোক মেমরি পূর্ণ না হয়), যেমন @ ভ্যালেনোক উল্লেখ করেছেন।
YvesgereY

6

স্ট্যাকটি x86 এ বৃদ্ধি পায় (আর্কিটেকচার দ্বারা সংজ্ঞায়িত, পপ ইনক্রিমেন্টস স্ট্যাক পয়েন্টার, পুশ হ্রাস))


5

MIPS এবং অনেক আধুনিক সালে আরআইএসসি আর্কিটেকচারের (পাওয়ারপিসি, আরআইএসসি-ফাইভ SPARC ... মত) সেখানে নেই pushএবং popনির্দেশাবলী। এই ক্রিয়াকলাপগুলি স্পষ্টভাবে স্ট্যাক পয়েন্টারটি ম্যানুয়ালি সমন্বয় করে সম্পন্ন হয় তারপরে মানটি লোড / স্টোর করে সামঞ্জস্য করা পয়েন্টারের তুলনায়। সমস্ত রেজিস্টার (শূন্য রেজিস্টার ব্যতীত) সাধারণ উদ্দেশ্য তাই তাত্ত্বিকভাবে যে কোনও নিবন্ধক স্ট্যাক পয়েন্টার হতে পারে, এবং স্ট্যাকার যে দিকনির্দেশে প্রোগ্রামার চায় সেগুলি বাড়তে পারে

এটি বলেছিল, সাধারণত স্ট্যাক এবং প্রোগ্রামের ডেটা বা হিপ ডেটা বড় হয় এবং একে অপরের সাথে সংঘর্ষ হয় যখন সম্ভবত এড়ানোর জন্য বেশিরভাগ আর্কিটেকচারে স্ট্যাকটি সাধারণত বৃদ্ধি পায়। এছাড়া মহান অ্যাড্রেসিং উল্লিখিত কারণে এর SH-এর উত্তর । কয়েকটি উদাহরণ: এমআইপিএস এবিআই নীচের দিকে বৃদ্ধি পায় এবং স্ট্যাক পয়েন্টার হিসাবে $29( $spএকে) ব্যবহার করুন , আরআইএসসি-ভি এবিআইও নীচের দিকে বৃদ্ধি পায় এবং স্ট্যাক পয়েন্টার হিসাবে এক্স 2 ব্যবহার করুন

ইন্টেল ৮০৫১-তে স্ট্যাকটি বড় হয়, সম্ভবত মেমরির স্থানটি এত ছোট (মূল সংস্করণে 128 বাইট) যে কোনও গাদা নেই এবং আপনাকে স্ট্যাকটি উপরে রাখার প্রয়োজন নেই যাতে এটি গাদা বাড়ার থেকে পৃথক হয়ে যায়'ll নীচ থেকে

আপনি বিভিন্ন আর্কিটেকচারে স্ট্যাকের ব্যবহার সম্পর্কে আরও তথ্য https://en.wikedia.org/wiki/Calling_convention এ খুঁজে পেতে পারেন

আরো দেখুন


2

অন্যান্য উত্তরগুলির সাথে সামান্য সংযোজন, যা আমি যতদূর দেখতে পাচ্ছি এই বিন্দুটি স্পর্শ করতে পারেনি:

স্ট্যাকটি নীচের দিকে বাড়ার সাথে সাথে স্ট্যাকের সমস্ত ঠিকানার স্ট্যাক পয়েন্টারের তুলনায় একটি ইতিবাচক অফসেট রয়েছে। নেতিবাচক অফসেটের কোনও প্রয়োজন নেই, কারণ তারা কেবল অব্যবহৃত স্ট্যাকের জায়গাতেই নির্দেশ করবে। প্রসেসর স্ট্যাকপয়েন্টার-আপেক্ষিক ঠিকানাকে সমর্থন করলে এটি স্ট্যাকের অবস্থানগুলিতে অ্যাক্সেসকে সহজতর করে।

অনেক প্রসেসরের এমন নির্দেশাবলী রয়েছে যা কিছু নিবন্ধের তুলনায় ইতিবাচক-অফসেটের সাথে অ্যাক্সেসের অনুমতি দেয়। এর মধ্যে রয়েছে অনেকগুলি আধুনিক স্থাপত্য, পাশাপাশি কিছু পুরানো include উদাহরণস্বরূপ, এআরএম থাম্ব এবিআই স্ট্যাকপয়েন্টার-আপেক্ষিক অ্যাক্সেসের জন্য একটি একক 16-বিট নির্দেশ শব্দের মধ্যে এনকোডেড পজিটিভ অফসেট সহ সরবরাহ করবে।

যদি স্ট্যাকটি উপরের দিকে বৃদ্ধি পায় তবে স্ট্যাকপয়েন্টারের সাথে সম্পর্কিত সমস্ত দরকারী অফসেটগুলি নেতিবাচক হবে, যা স্বজ্ঞাত এবং কম সুবিধাজনক is এটি রেজিস্টার-আপেক্ষিক ঠিকানার অন্যান্য অ্যাপ্লিকেশনগুলির সাথেও মতবিরোধ রয়েছে, উদাহরণস্বরূপ কোনও কাঠামোর ক্ষেত্রগুলি অ্যাক্সেস করার জন্য।


2

বেশিরভাগ সিস্টেমে, স্ট্যাকটি কমতে থাকে এবং https://gist.github.com/cpq/8598782 এ আমার নিবন্ধটি কেন তা বাড়ছে তা ব্যাখ্যা করে। এটি সহজ: মেমরির একটি স্থির অংশে দুটি ক্রমবর্ধমান মেমরি ব্লক (হিপ এবং স্ট্যাক) কীভাবে বিন্যাস করবেন? সর্বোত্তম সমাধান হ'ল এগুলিকে বিপরীত প্রান্তে রেখে একে অপরের দিকে বাড়তে দেওয়া।


যে সারকথা এখন মৃত মনে করা হয় :(
ভেন

@ ভেন - আমি এটি পেতে পারি
ব্রেট হলম্যান

1

এটি হ্রাস পায় কারণ প্রোগ্রামে বরাদ্দকৃত মেমরিটির নীচে নিজেই প্রোগ্রামটির জন্য "স্থায়ী ডেটা" অর্থাত্ কোড থাকে, তারপরে মাঝখানে গাদা। স্ট্যাকটি রেফারেন্স করার জন্য আপনার আর একটি নির্দিষ্ট পয়েন্ট প্রয়োজন, যাতে আপনাকে শীর্ষে ছেড়ে যায়। এর অর্থ হ'ল স্ট্যাকটি নীচে বাড়ছে, যতক্ষণ না এটি স্তূপের অবজেক্টগুলির সাথে সম্ভাব্য সংলগ্ন হয়।


0

এই ম্যাক্রোর এটি ইউবি ছাড়াই রানটাইমে সনাক্ত করা উচিত:

#define stk_grows_up_eh() stk_grows_up__(&(char){0})
_Bool stk_grows_up__(char *ParentsLocal);

__attribute((__noinline__))
_Bool stk_grows_up__(char *ParentsLocal) { 
    return (uintptr_t)ParentsLocal < (uintptr_t)&ParentsLocal;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.