আমি সি তে কিছু প্রশিক্ষণ উপকরণ প্রস্তুত করছি এবং আমি চাই আমার উদাহরণগুলি সাধারণ স্ট্যাকের মডেলের সাথে মানিয়ে নিতে।
লিনাক্স, উইন্ডোজ, ম্যাক ওএসএক্স (পিপিসি এবং এক্স 86), সোলারিস এবং সর্বাধিক সাম্প্রতিক ইউনিক্সগুলিতে কোন সি স্ট্যাক বৃদ্ধি পাচ্ছে?
আমি সি তে কিছু প্রশিক্ষণ উপকরণ প্রস্তুত করছি এবং আমি চাই আমার উদাহরণগুলি সাধারণ স্ট্যাকের মডেলের সাথে মানিয়ে নিতে।
লিনাক্স, উইন্ডোজ, ম্যাক ওএসএক্স (পিপিসি এবং এক্স 86), সোলারিস এবং সর্বাধিক সাম্প্রতিক ইউনিক্সগুলিতে কোন সি স্ট্যাক বৃদ্ধি পাচ্ছে?
উত্তর:
স্ট্যাক বৃদ্ধি সাধারণত অপারেটিং সিস্টেমের উপর নির্ভর করে না, তবে প্রসেসরের উপর এটি চলছে। উদাহরণস্বরূপ, সোলারিস x86 এবং SPARC এ চলে। ম্যাক ওএসএক্স (যেমন আপনি উল্লেখ করেছেন) পিপিসি এবং x86 এ চলে। লিনাক্স আমার বড় হিনকিন 'সিস্টেম z থেকে শুরু করে একটি ছোট্ট কব্জি ঘড়ি পর্যন্ত কাজ করে ।
সিপিইউ যদি কোনও ধরণের পছন্দ সরবরাহ করে তবে ওএস দ্বারা ব্যবহৃত এবিআই / কলিং কনভেনশন আপনার কোডটি অন্যের কোডকে কল করতে চাইলে আপনাকে কোন পছন্দ করতে হবে তা নির্দিষ্ট করে।
প্রসেসর এবং তাদের দিকনির্দেশ:
শেষ কয়েকটির উপরে আমার বয়স দেখানো হচ্ছে, 1802 হ'ল চিপটি প্রারম্ভিক শাটলগুলি নিয়ন্ত্রণ করার জন্য ব্যবহৃত হত (অনুভূত হয় যে দরজাগুলি উন্মুক্ত ছিল কিনা, আমি সন্দেহ করি, এটির প্রসেসিং পাওয়ারের ভিত্তিতে :-) এবং আমার দ্বিতীয় কম্পিউটার, COMX-35 ( আমার জেডএক্স 80 অনুসরণ করে )।
PDP11 থেকে উত্পন্ন বিশদ বিবরণ এখানে থেকে 8051 বিস্তারিত এখানে ।
স্পার্ক আর্কিটেকচারটিতে একটি স্লাইডিং উইন্ডো রেজিস্ট্রার মডেল ব্যবহার করা হয়। স্থাপত্যগতভাবে দৃশ্যমান বিবরণগুলির মধ্যে রেজিস্টার-উইন্ডোগুলির একটি বিজ্ঞপ্তি বাফারও অন্তর্ভুক্ত রয়েছে যা বৈধ এবং অভ্যন্তরীণভাবে ক্যাশে থাকে, যখন ফাঁদগুলি ওভার / প্রবাহিত হয়। বিশদ জন্য এখানে দেখুন । যেমন SPARCv8 ম্যানুয়ালটি ব্যাখ্যা করে , সংরক্ষণ এবং পুনরুদ্ধার নির্দেশাবলী ADD নির্দেশাবলী প্লাস্টিক -উইন্ডো ঘোরানোর মতো। স্বাভাবিক নেতিবাচক পরিবর্তে ইতিবাচক ধ্রুবক ব্যবহার করা একটি upর্ধ্বগামী বর্ধিত স্ট্যাক দেয়।
পূর্বোক্ত এসসিআরটি কৌশলটি অন্যটি হ'ল - 1802 এসসিআরটি (স্ট্যান্ডার্ড কল এবং রিটার্ন কৌশল) এর জন্য 16 বা বিট রেজিস্ট্রার ব্যবহার করেছে বা এটি 16 টি ব্যবহার করেছে। একটি প্রোগ্রামের কাউন্টার ছিল, আপনি SEP Rn
নির্দেশের সাথে পিসি হিসাবে যে কোনও নিবন্ধক ব্যবহার করতে পারেন । একটি ছিল স্ট্যাক পয়েন্টার এবং দু'টি সর্বদা এসসিআরটি কোড ঠিকানার দিকে নির্দেশ করার জন্য সেট করা হয়েছিল, একটি কল করার জন্য, একটি ফেরতের জন্য। কোনও রেজিস্টারকে বিশেষভাবে চিকিত্সা করা হয়নি। মনে রাখবেন এই বিবরণগুলি মেমরি থেকে এসেছে, সেগুলি পুরোপুরি সঠিক হতে পারে না।
উদাহরণস্বরূপ, যদি আর 3 পিসি হয়, আর 4 এসসিআরটি কল ঠিকানা ছিল, আর 5 হ'ল এসসিআরটি রিটার্ন ঠিকানা এবং আর 2 ছিল "স্ট্যাক" (এটি সফ্টওয়্যারটিতে প্রয়োগিত হিসাবে উদ্ধৃতিগুলি), SEP R4
R4 কে পিসি হিসাবে সেট করবে এবং এসসিআরটি চালানো শুরু করবে কল কোড
এটা তোলে তারপর, R2 হলো "স্ট্যাকের" (আমি মনে করি R6 টেম্প সঞ্চয় করার জন্য ব্যবহার করা হয়েছিল) এ R3 সংরক্ষণ করবে এটি আপ সামঞ্জস্য বা ডাউন, R3 নিম্নলিখিত দুটি বাইট দখল, তাদের লোড মধ্যে R3, তারপর না SEP R3
এবং নতুন ঠিকানায় চলমান হতে।
ফিরে আসার জন্য, এটি SEP R5
যা পুরানো ঠিকানাটি আর 2 স্ট্যাকের বাইরে টেনে তুলবে, এতে দুটি যুক্ত করুন (কলের ঠিকানা বাইটগুলি এড়িয়ে যেতে), এটি R3 এ লোড করুন এবং SEP R3
পূর্ববর্তী কোডটি চালানো শুরু করবেন।
আপনার 6502/6809 / z80 স্ট্যাক-ভিত্তিক কোডের পরে প্রথমে আপনার মাথাটি গুটিয়ে ফেলা খুব কঠিন তবে প্রাচীরের ধারে-বিপরীতমুখী উপায়টিতে এখনও দুর্দান্ত leg এছাড়াও চিপের বড় বিক্রয় বৈশিষ্ট্যগুলির মধ্যে একটি ছিল 16 16-বিট রেজিস্টারগুলির একটি সম্পূর্ণ স্যুট, যদিও আপনি তাত্ক্ষণিকভাবে তাদের মধ্যে 7 টি হারিয়ে ফেলেছেন (এসসিআরটি-এর জন্য 5 জন, ডিএমএর জন্য দুটি এবং স্মৃতি থেকে বিঘ্নিত)। আহ, বাস্তবতার ওপরে বিপণনের বিজয় :-)
সিস্টেম জেডটি আসলে একইরকম, কল / রিটার্নের জন্য এর আর 14 এবং আর 15 রেজিস্টার ব্যবহার করে।
সি ++ এ (সি এর সাথে অভিযোজিত) স্ট্যাক সি সি :
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);
}
}
static
। পরিবর্তে আপনি ঠিকানাটি পুনরাবৃত্তির কল হিসাবে যুক্তি হিসাবে পাস করতে পারেন।
static
আপনি যদি একাধিক বার কল করেন তবে পরবর্তী কলগুলি ব্যর্থ হতে পারে ...
পুরানো সিস্টেমে নীচে বাড়ার সুবিধা হ'ল স্ট্যাকটি সাধারণত মেমরির শীর্ষে ছিল। প্রোগ্রামগুলি সাধারণত নিচ থেকে শুরু হয়ে থাকে মেমরির এই ধরণের মেমরি পরিচালনার ফলে স্ট্যাকের নীচে কোথাও বোধগম্যতা পরিমাপ করার এবং রাখার প্রয়োজনীয়তা হ্রাস পায়।
MIPS এবং অনেক আধুনিক সালে আরআইএসসি আর্কিটেকচারের (পাওয়ারপিসি, আরআইএসসি-ফাইভ SPARC ... মত) সেখানে নেই push
এবং pop
নির্দেশাবলী। এই ক্রিয়াকলাপগুলি স্পষ্টভাবে স্ট্যাক পয়েন্টারটি ম্যানুয়ালি সমন্বয় করে সম্পন্ন হয় তারপরে মানটি লোড / স্টোর করে সামঞ্জস্য করা পয়েন্টারের তুলনায়। সমস্ত রেজিস্টার (শূন্য রেজিস্টার ব্যতীত) সাধারণ উদ্দেশ্য তাই তাত্ত্বিকভাবে যে কোনও নিবন্ধক স্ট্যাক পয়েন্টার হতে পারে, এবং স্ট্যাকার যে দিকনির্দেশে প্রোগ্রামার চায় সেগুলি বাড়তে পারে
এটি বলেছিল, সাধারণত স্ট্যাক এবং প্রোগ্রামের ডেটা বা হিপ ডেটা বড় হয় এবং একে অপরের সাথে সংঘর্ষ হয় যখন সম্ভবত এড়ানোর জন্য বেশিরভাগ আর্কিটেকচারে স্ট্যাকটি সাধারণত বৃদ্ধি পায়। এছাড়া মহান অ্যাড্রেসিং উল্লিখিত কারণে এর SH-এর উত্তর । কয়েকটি উদাহরণ: এমআইপিএস এবিআই নীচের দিকে বৃদ্ধি পায় এবং স্ট্যাক পয়েন্টার হিসাবে $29
( $sp
একে) ব্যবহার করুন , আরআইএসসি-ভি এবিআইও নীচের দিকে বৃদ্ধি পায় এবং স্ট্যাক পয়েন্টার হিসাবে এক্স 2 ব্যবহার করুন
ইন্টেল ৮০৫১-তে স্ট্যাকটি বড় হয়, সম্ভবত মেমরির স্থানটি এত ছোট (মূল সংস্করণে 128 বাইট) যে কোনও গাদা নেই এবং আপনাকে স্ট্যাকটি উপরে রাখার প্রয়োজন নেই যাতে এটি গাদা বাড়ার থেকে পৃথক হয়ে যায়'ll নীচ থেকে
আপনি বিভিন্ন আর্কিটেকচারে স্ট্যাকের ব্যবহার সম্পর্কে আরও তথ্য https://en.wikedia.org/wiki/Calling_convention এ খুঁজে পেতে পারেন
আরো দেখুন
অন্যান্য উত্তরগুলির সাথে সামান্য সংযোজন, যা আমি যতদূর দেখতে পাচ্ছি এই বিন্দুটি স্পর্শ করতে পারেনি:
স্ট্যাকটি নীচের দিকে বাড়ার সাথে সাথে স্ট্যাকের সমস্ত ঠিকানার স্ট্যাক পয়েন্টারের তুলনায় একটি ইতিবাচক অফসেট রয়েছে। নেতিবাচক অফসেটের কোনও প্রয়োজন নেই, কারণ তারা কেবল অব্যবহৃত স্ট্যাকের জায়গাতেই নির্দেশ করবে। প্রসেসর স্ট্যাকপয়েন্টার-আপেক্ষিক ঠিকানাকে সমর্থন করলে এটি স্ট্যাকের অবস্থানগুলিতে অ্যাক্সেসকে সহজতর করে।
অনেক প্রসেসরের এমন নির্দেশাবলী রয়েছে যা কিছু নিবন্ধের তুলনায় ইতিবাচক-অফসেটের সাথে অ্যাক্সেসের অনুমতি দেয়। এর মধ্যে রয়েছে অনেকগুলি আধুনিক স্থাপত্য, পাশাপাশি কিছু পুরানো include উদাহরণস্বরূপ, এআরএম থাম্ব এবিআই স্ট্যাকপয়েন্টার-আপেক্ষিক অ্যাক্সেসের জন্য একটি একক 16-বিট নির্দেশ শব্দের মধ্যে এনকোডেড পজিটিভ অফসেট সহ সরবরাহ করবে।
যদি স্ট্যাকটি উপরের দিকে বৃদ্ধি পায় তবে স্ট্যাকপয়েন্টারের সাথে সম্পর্কিত সমস্ত দরকারী অফসেটগুলি নেতিবাচক হবে, যা স্বজ্ঞাত এবং কম সুবিধাজনক is এটি রেজিস্টার-আপেক্ষিক ঠিকানার অন্যান্য অ্যাপ্লিকেশনগুলির সাথেও মতবিরোধ রয়েছে, উদাহরণস্বরূপ কোনও কাঠামোর ক্ষেত্রগুলি অ্যাক্সেস করার জন্য।
বেশিরভাগ সিস্টেমে, স্ট্যাকটি কমতে থাকে এবং https://gist.github.com/cpq/8598782 এ আমার নিবন্ধটি কেন তা বাড়ছে তা ব্যাখ্যা করে। এটি সহজ: মেমরির একটি স্থির অংশে দুটি ক্রমবর্ধমান মেমরি ব্লক (হিপ এবং স্ট্যাক) কীভাবে বিন্যাস করবেন? সর্বোত্তম সমাধান হ'ল এগুলিকে বিপরীত প্রান্তে রেখে একে অপরের দিকে বাড়তে দেওয়া।
এটি হ্রাস পায় কারণ প্রোগ্রামে বরাদ্দকৃত মেমরিটির নীচে নিজেই প্রোগ্রামটির জন্য "স্থায়ী ডেটা" অর্থাত্ কোড থাকে, তারপরে মাঝখানে গাদা। স্ট্যাকটি রেফারেন্স করার জন্য আপনার আর একটি নির্দিষ্ট পয়েন্ট প্রয়োজন, যাতে আপনাকে শীর্ষে ছেড়ে যায়। এর অর্থ হ'ল স্ট্যাকটি নীচে বাড়ছে, যতক্ষণ না এটি স্তূপের অবজেক্টগুলির সাথে সম্ভাব্য সংলগ্ন হয়।