অ্যাড্রেসিং মোড
এই পাঠে যা শিখবেন
- অ্যাড্রেসিং মোড কী এবং কেন এটি প্রতিটি ইনস্ট্রাকশনের operand ব্যাখ্যায় জরুরি
- পাঁচটি সাধারণ অ্যাড্রেসিং মোড — immediate, register, direct, register indirect, indexed — এবং প্রতিটির বাস্তব ব্যবহার
- কীভাবে একই সংখ্যাসূচক operand ফিল্ড ভিন্ন মোডে সম্পূর্ণ ভিন্ন প্রকৃত মান নির্দেশ করতে পারে
- register indirect ও indexed addressing কীভাবে C-এর মতো ভাষায় পয়েন্টার ও অ্যারে ইনডেক্সিং-এর ভিত্তি
১ · অ্যাড্রেসিং মোড কী
L24-এ আমরা দেখেছি একটি ইনস্ট্রাকশনের operand ফিল্ড শুধুই একটি সংখ্যা (যেমন rs2 বা imm ফিল্ডে থাকা বিট প্যাটার্ন)। কিন্তু সেই সংখ্যাটির প্রকৃত অর্থ কী — এটি কি নিজেই ব্যবহারযোগ্য মান, নাকি একটি রেজিস্টার নম্বর, নাকি একটি মেমরি অ্যাড্রেস? এই প্রশ্নের উত্তর দেয় অ্যাড্রেসিং মোড — একটি ইনস্ট্রাকশনের operand ফিল্ডকে কীভাবে ইন্টারপ্রেট করে আসল ডেটার অবস্থান (বা মান) খুঁজে বের করতে হবে, তার নিয়ম। ভিন্ন ভিন্ন অ্যাড্রেসিং মোড ভিন্ন ভিন্ন বাস্তব প্রয়োজন মেটায় — কখনো গতি প্রাধান্য পায়, কখনো নমনীয়তা।
২ · পাঁচটি সাধারণ অ্যাড্রেসিং মোড
Immediate Addressing
operand-ই সরাসরি ইনস্ট্রাকশনে এমবেড করা constant মান — L24-এর I-type ফরম্যাটের imm ফিল্ড এর সরাসরি
উদাহরণ। সবচেয়ে দ্রুত, কারণ মান পেতে কোনো মেমরি বা রেজিস্টার অ্যাক্সেস লাগে না — কিন্তু ইনস্ট্রাকশনের immediate
ফিল্ডের বিট-প্রস্থে যা ধরে, ততটুকু রেঞ্জের মধ্যেই সীমাবদ্ধ থাকতে হয়।
Register Addressing
operand হলো একটি নির্দিষ্ট রেজিস্টারে বর্তমানে থাকা মান — সরাসরি রেজিস্টার ফাইল অ্যাক্সেস (M5/L26-এ বিস্তারিত), তাই খুবই দ্রুত।
Direct / Absolute Addressing
ইনস্ট্রাকশনে সরাসরি operand-এর সঠিক মেমরি অ্যাড্রেস লেখা থাকে — হার্ডওয়্যার সেই অ্যাড্রেসে সরাসরি গিয়ে মান আনে।
Register Indirect Addressing
একটি রেজিস্টারে একটি মেমরি অ্যাড্রেস (একটি "পয়েন্টার") রাখা থাকে, আর প্রকৃত operand সেই
মেমরি লোকেশন থেকে আনা হয় — C-এর মতো ভাষায় পয়েন্টার (*ptr) ঠিক এইভাবেই কাজ করে, সরাসরি এই
অ্যাড্রেসিং মোডের উপর ভিত্তি করে।
Indexed / Displacement Addressing
effective address = base register-এর মান + একটি constant offset। এটিই কম্পাইল করা কোডে array[i]-এর
মতো অ্যারে ইনডেক্সিং বা struct field access-এর পেছনের প্রকৃত হার্ডওয়্যার মেকানিজম — base register অ্যারের
শুরুর অ্যাড্রেস ধরে রাখে, আর offset হিসাব হয় ইনডেক্স i থেকে।
operand = constant নিজেই — সবচেয়ে দ্রুত, কিন্তু সীমিত রেঞ্জ।
operand = একটি রেজিস্টারের মান — দ্রুত রেজিস্টার-ফাইল অ্যাক্সেস।
operand = নির্দিষ্ট মেমরি অ্যাড্রেসের মান।
রেজিস্টারে অ্যাড্রেস (পয়েন্টার), সেই অ্যাড্রেস থেকে মান — C-এর
*ptr।effective address = base + offset — অ্যারে ইনডেক্সিং
array[i]-এর ভিত্তি।
নিচের কোড সেলে একটি ছোট্ট টয় মেশিন-স্টেট (registers ও memory ডিকশনারি) বানিয়ে
পাঁচটি মোড অনুযায়ী resolve_operand ফাংশন লেখা হচ্ছে — লক্ষ্য করুন কীভাবে একই সংখ্যা 4
ভিন্ন মোডে সম্পূর্ণ ভিন্ন প্রকৃত মান নির্দেশ করে।
# একটি টয় মেশিন-স্টেট -- বাস্তব হার্ডওয়্যার নয়, শুধুই ধারণা বোঝানোর সিমুলেশন
registers = {0: 0, 1: 100, 2: 4, 3: 7}
memory = {4: 55, 100: 999, 104: 42}
def resolve_operand(mode, operand_field, registers, memory):
"""একই operand_field ভিন্ন mode অনুযায়ী ভিন্ন প্রকৃত মান রিটার্ন করে"""
if mode == "immediate":
return operand_field
elif mode == "register":
return registers[operand_field]
elif mode == "direct":
return memory[operand_field]
elif mode == "register_indirect":
pointer_address = registers[operand_field]
return memory[pointer_address]
elif mode == "indexed":
base_reg, offset = operand_field
effective_address = registers[base_reg] + offset
return memory[effective_address]
raise ValueError(f"অজানা অ্যাড্রেসিং মোড: {mode}")
# --- একই সংখ্যা 4 বিভিন্ন মোডে সম্পূর্ণ ভিন্ন প্রকৃত মান নির্দেশ করছে ---
print("immediate, operand=4 ->", resolve_operand("immediate", 4, registers, memory))
print("register, operand=2 -> registers[2] =", resolve_operand("register", 2, registers, memory))
print("direct, operand=4 -> memory[4] =", resolve_operand("direct", 4, registers, memory))
print("register_indirect, operand=1-> memory[registers[1]] =", resolve_operand("register_indirect", 1, registers, memory))
print("indexed, operand=(reg1, +4) -> memory[registers[1]+4] =", resolve_operand("indexed", (1, 4), registers, memory))
direct মোডে operand=4 মানে "মেমরি অ্যাড্রেস 4-এ যা আছে" (ফলাফল 55), অথচ
register_indirect মোডে operand=1 মানে "রেজিস্টার 1-এ থাকা অ্যাড্রেসে (100) যা আছে" (ফলাফল 999) —
operand ফিল্ড দেখলেই বোঝা যায় না প্রকৃত মান কী হবে, ঠিক অ্যাড্রেসিং মোডটাও জানা লাগে। এটাই ঠিক কেন প্রতিটি
ইনস্ট্রাকশন ফরম্যাটে (L24) অ্যাড্রেসিং মোড কোনো না কোনোভাবে এনকোড করা থাকে।
অ্যাড্রেসিং মোড হলো operand ফিল্ড থেকে প্রকৃত ডেটায় পৌঁছানোর "নির্দেশিকা" — Immediate ও Register সবচেয়ে দ্রুত (extra memory access লাগে না), Direct ও Register Indirect মেমরি অ্যাক্সেস করে (কম্পাইলারে পয়েন্টারের ভিত্তি), আর Indexed addressing অ্যারে ও struct-এর মতো ডেটা স্ট্রাকচার অ্যাক্সেস করার হার্ডওয়্যার মেকানিজম সরবরাহ করে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ Register Indirect আর Indexed addressing দুটোই তো রেজিস্টার থেকে মেমরি অ্যাক্সেস করে — তাহলে দুটোর মধ্যে আসল পার্থক্য কী?
Register Indirect-এ effective address ঠিক রেজিস্টারে থাকা মানই — কোনো অতিরিক্ত offset যোগ হয় না
(address = registers[reg])। Indexed addressing-এ effective address হলো রেজিস্টারের মানের
সাথে একটি অতিরিক্ত constant offset যোগ করে বের করা (address = registers[reg] + offset)।
এই ছোট্ট পার্থক্যটাই ব্যবহারিকভাবে বিশাল — Register Indirect একটি একক মান পয়েন্ট করে (যেমন C-এর
*ptr), অথচ Indexed addressing একই base থেকে ভিন্ন ভিন্ন offset দিয়ে একটি গোটা অ্যারের
বিভিন্ন উপাদান অ্যাক্সেস করতে দেয় (যেমন array[0], array[1], array[2]...) — base register
অপরিবর্তিত রেখেই।
প্র ০২ Immediate addressing সবচেয়ে দ্রুত হলেও কেন সব জায়গায় এটি ব্যবহার করা যায় না?
কারণ immediate মান ইনস্ট্রাকশনের ভেতরেই এমবেড থাকতে হয় (L24-এর imm ফিল্ড, উদাহরণে মাত্র ৬ বিট), তাই এর রেঞ্জ ফিক্সড ইনস্ট্রাকশন-দৈর্ঘ্যের কারণে সীমাবদ্ধ থাকে — একটি প্রোগ্রাম চলাকালীন গণনা করা ডায়নামিক মান (যেমন একটি ফাংশনের রিটার্ন ভ্যালু, বা ব্যবহারকারীর ইনপুট) কখনোই ইনস্ট্রাকশনে আগে থেকে এমবেড করা সম্ভব নয় — এই ধরনের রানটাইম মান অবশ্যই রেজিস্টার বা মেমরিতে থাকতে হবে, তাই Register বা মেমরি-ভিত্তিক অ্যাড্রেসিং মোডই একমাত্র উপায়।
প্র ০৩
C প্রোগ্রামিং-এ একটি পয়েন্টার ভেরিয়েবল (int *p) ব্যবহার করা এই পাঠের কোন অ্যাড্রেসিং মোডের সাথে সবচেয়ে সরাসরি সম্পর্কিত, এবং কেন?
Register Indirect Addressing-এর সাথে সরাসরি সম্পর্কিত — একটি পয়েন্টার ভেরিয়েবল p কম্পাইল
হয়ে একটি রেজিস্টারে (বা মেমরি লোকেশনে) একটি মেমরি অ্যাড্রেস (অন্য কোনো ভেরিয়েবলের অবস্থান) সংরক্ষণ করে —
ঠিক যেমন এই মোডে একটি রেজিস্টার নিজে ডেটা না রেখে একটি অ্যাড্রেস রাখে। *p লিখলে (dereference)
কম্পাইলার হার্ডওয়্যারকে ঠিক এই মোডেই বলে — "এই রেজিস্টারে থাকা অ্যাড্রেসে গিয়ে যে মান আছে সেটা আনো।"
অনুশীলন
-
হাতে-কলমে করুন: উপরের কোডের
registersওmemoryস্টেট ব্যবহার করে,indexedমোডেoperand_field = (0, 4)(অর্থাৎ base register = register 0, offset = 4) দিলে effective address ও ফলাফল কী হবে হাতে-কলমে বের করুন, তারপর কোড চালিয়ে মিলিয়ে দেখুন।registers[0] = 0, তাই effective address = 0 + 4 = 4। memory[4] = 55। তাই
resolve_operand("indexed", (0, 4), registers, memory)এর ফলাফল হবে 55 — লক্ষ্য করুন এটি ঠিকdirectমোডে operand=4 দিলে যা পাওয়া গিয়েছিল তার সমান, কারণ register 0-এর মান 0 হওয়ায় কোনো প্রকৃত অফসেট যোগ হয়নি। -
চিন্তা করুন: কোডের
registersডিকশনারিতে register 3-এর মান 7, কিন্তুmemory-তে কোনো কী (key) 7 নেই। যদি কেউresolve_operand("register_indirect", 3, registers, memory)কল করে, কী ঘটবে বলে মনে হয়, এবং বাস্তব হার্ডওয়্যারে এর সমতুল্য পরিস্থিতি কী?Python-এ
memory[7]অ্যাক্সেস করার চেষ্টা করলেKeyErrorরেইজ হবে, কারণ memory ডিকশনারিতে key 7 নেই। বাস্তব হার্ডওয়্যারে এর সমতুল্য পরিস্থিতি হলো একটি ইনভ্যালিড মেমরি অ্যাক্সেস — একটি পয়েন্টার যদি এমন কোনো অ্যাড্রেসে নির্দেশ করে যা প্রোগ্রামের জন্য বরাদ্দ করা নেই, তাহলে CPU একটি "সেগমেন্টেশন ফল্ট"-এর মতো হার্ডওয়্যার এক্সসেপশন তৈরি করে (M7/L36-এ এক্সসেপশন হ্যান্ডলিং বিস্তারিত আসবে) — এটিই একটি বাস্তব, গুরুতর বাগের ক্লাসিক উদাহরণ (dangling/invalid পয়েন্টার ডিরেফারেন্স করা)।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ M5-এর তৃতীয় পাঠ — পরের পাঠে দেখব রেজিস্টার ফাইল আসলে কীভাবে হার্ডওয়্যারে সংগঠিত থাকে।
- L26 · রেজিস্টার ফাইল ও CPU রেজিস্টার পরবর্তী পাঠ Register ও Register Indirect অ্যাড্রেসিং মোড যে রেজিস্টার ফাইল অ্যাক্সেস করে, তার ভেতরের গঠন।
- L24 · ইনস্ট্রাকশন ফরম্যাট ও এনকোডিং সম্পর্কিত পাঠ অ্যাড্রেসিং মোড যে operand ফিল্ড ইন্টারপ্রেট করে, সেই ফিল্ড কীভাবে ইনস্ট্রাকশনে এনকোড হয়।