অন্যান্য উত্তরগুলি কেবলমাত্র এমন একটি এনওপি বিবেচনা করছে যা আসলে কোনও সময়ে কার্যকর হয় - যা বেশ সাধারণভাবে ব্যবহৃত হয়, তবে এটি কেবল এনওপি-র ব্যবহার নয়।
অ নির্বাহ NOP যখন কোডটি patched করা যেতে পারে লেখার বেশ উপকারী - মূলত, আপনি যা করবেন প্যাড কয়েক NOPs সঙ্গে ফাংশন পরRET
(বা অনুরূপ নির্দেশ)। যখন আপনাকে এক্সিকিউটেবল প্যাচ করতে হয়, আপনি সহজেই মূল থেকে শুরু করে ফাংশনে আরও কোড যুক্ত করতে পারেন RET
এবং আপনার প্রয়োজনীয় যতগুলি এনওপি ব্যবহার করা হয় (যেমন দীর্ঘ জাম্প বা এমনকি ইনলাইন কোডের জন্য) এবং অন্যটির সাথে শেষ করে RET
।
এই ব্যবহারের ক্ষেত্রে, কোনওরও কখনই NOP
মৃত্যুদন্ড কার্যকর করার প্রত্যাশা করে না। এক্সিকিউটেবল প্যাচিংয়ের একমাত্র পয়েন্টটি হ'ল - তাত্ত্বিক নন-প্যাডেড এক্সিকিউটেবলের মধ্যে, আপনাকে আসলে ফাংশনের কোডটি নিজেই পরিবর্তন করতে হবে (কখনও কখনও এটি মূল সীমানা মাপসই করতে পারে তবে বেশিরভাগ ক্ষেত্রেই আপনাকে যাইহোকের প্রয়োজন হবে) ) - এটি অনেক জটিল, বিশেষত ম্যানুয়ালি লিখিত সমাবেশ বা একটি অনুকূলিতকরণ সংকলক বিবেচনা করে; আপনাকে জাম্প এবং অনুরূপ নির্মানকে সম্মান করতে হবে যা কিছু গুরুত্বপূর্ণ কোডের দিকে নির্দেশ করতে পারে। সব মিলিয়ে বেশ কৌতূহলপূর্ণ।
অবশ্যই, এই আরো অনেক প্রচন্ডভাবে, সেকালের দিন ব্যবহার যখন এটি এই মত প্যাচ করতে দরকারী ছিল ছোট এবং অনলাইন । আজ, আপনি কেবল একটি পুনরায় সংশ্লেষিত বাইনারি বিতরণ করবেন এবং এটি সম্পন্ন করুন। এখনও কিছু রয়েছে যারা প্যাচিং এনওপি ব্যবহার করে (কার্যকর করা হয় বা না, এবং সবসময় আক্ষরিক নয় NOP
- উদাহরণস্বরূপ, উইন্ডোজ MOV EDI, EDI
অনলাইনে প্যাচিংয়ের জন্য ব্যবহার করে - এটি সেই ধরণের যেখানে আপনি সিস্টেম লাইব্রেরি আপডেট করতে পারবেন যখন সিস্টেমটি চলমান চলাকালীন, পুনরায় আরম্ভের প্রয়োজন ছাড়াই)।
সুতরাং সর্বশেষ প্রশ্নটি হল, কেন এমন কিছু যা সত্যিই কিছু করে না তার জন্য একটি উত্সর্গীকৃত নির্দেশনা রয়েছে?
- এটি একটি আসল নির্দেশ - ডিবাগিং বা হ্যান্ডকোডিং অ্যাসেম্বলির সময় গুরুত্বপূর্ণ। মত নির্দেশাবলী
MOV AX, AX
হুবহু একই কাজ করবে, তবে উদ্দেশ্যটি এতটা স্পষ্টভাবে সংকেত দেয় না।
- প্যাডিং - "কোড" যা কেবলমাত্র সারিবদ্ধকরণের উপর নির্ভর করে কোডের সামগ্রিক কর্মক্ষমতা উন্নত করতে পারে। এটি কখনই মৃত্যুদন্ড কার্যকর করা উচিত নয়। কিছু ডিবাগারগুলি সহজেই তাদের বিচ্ছিন্নতায় প্যাডিং এনওপিগুলি লুকিয়ে রাখেন।
- এটি সংকলকগুলির অনুকূলকরণের জন্য আরও স্থান দেয় - এখনও ব্যবহৃত প্যাটার্নটি হ'ল আপনি সংকলনের দুটি ধাপ পেয়েছেন, প্রথমটি বরং সরল এবং প্রচুর অপ্রয়োজনীয় সমাবেশ কোড উত্পাদন করছে, যখন দ্বিতীয়টি মুছে ফেলা হয়, ঠিকানা উল্লেখগুলি পুনর্বিবেচনা করে এবং অপসারণ করে বহিরাগত নির্দেশাবলী। এটি প্রায়শই জেআইটি-সংকলিত ভাষায়ও দেখা যায় -। নেট এর আইএল এবং জেভিএম-এর বাইট-কোড ব্যবহার
NOP
অনেকটা; প্রকৃত সংকলিত অ্যাসেম্বলি কোডের আর এগুলি নেই। এটি লক্ষ করা উচিত যে সেগুলি NOP
যদিও x86- গুলি নয় ।
- এটি অনলাইন ডিবাগিংকে উভয়ই পড়ার জন্য সহজ করে তোলে (প্রাক-
NOP
শূন্যপদ মেমরিটি সর্বজনীন হয়ে উঠবে, বিচ্ছিন্নভাবে পড়া সহজ করে তোলে) এবং হট-প্যাচিংয়ের জন্য (যদিও আমি ভিজ্যুয়াল স্টুডিওতে সম্পাদনা এবং চালিয়ে যাওয়া পছন্দ করি: পি)।
এনওপিগুলি কার্যকর করার জন্য অবশ্যই আরও কয়েকটি পয়েন্ট রয়েছে:
- পারফরম্যান্স, অবশ্যই - এটি কেন এটি 8085-এ ছিল না, তবে এমনকি 80486 এর মধ্যে ইতিমধ্যে পাইপলাইনযুক্ত নির্দেশনা কার্যকর করা হয়েছিল, যা "কিছুই না করা" কিছুটা কৌতুকপূর্ণ করে তোলে।
- যেমন দেখা গেছে
MOV EDI, EDI
, আক্ষরিকের চেয়ে আরও কার্যকর এনওপি রয়েছে NOP
। MOV EDI, EDI
x86 এ 2-বাইট এনওপি হিসাবে সেরা অভিনয় রয়েছে। আপনি যদি দুটি ব্যবহার করেন NOP
, তবে এটি কার্যকর করার জন্য দুটি নির্দেশিকা হবে।
সম্পাদনা করুন:
আসলে, @ দিমিত্রিগ্রিরিভের সাথে আলোচনার ফলে আমাকে এটি সম্পর্কে আরও কিছুটা ভাবতে বাধ্য করেছে, এবং আমি মনে করি এটি এই প্রশ্ন / উত্তরের একটি মূল্যবান সংযোজন, তাই আমাকে আরও কিছু বিট যোগ করতে দিন:
প্রথমত, বিন্দুটি, স্পষ্টতই - কেন এমন কোনও নির্দেশনা থাকবে যা এমন কিছু করে mov ax, ax
? উদাহরণস্বরূপ, আসুন 8086 মেশিন কোড (এমনকি 386 মেশিন কোডের চেয়ে পুরানো) এর ক্ষেত্রে দেখুন:
- অপকোড সহ একটি নিবেদিত এনওপি নির্দেশনা রয়েছে
0x90
। এটি এখনও সেই সময় যখন বহু লোক সমাবেশে লিখেছিল, মনে রাখবেন। সুতরাং যদি কোনও উত্সর্গীকৃত NOP
নির্দেশ না পাওয়া যায় তবে NOP
কীওয়ার্ডটি (ওরফে / মিমোনমিক) এখনও কার্যকর হবে এবং এটিতে মানচিত্র তৈরি হবে।
MOV
প্রকৃতপক্ষে অনেকগুলি বিভিন্ন অপকোডে মানচিত্রের মতো নির্দেশনা , কারণ এটি সময় এবং স্থানের সঞ্চয় করে - উদাহরণস্বরূপ, mov al, 42
" al
রেজিস্টারে তাত্ক্ষণিক বাইট সরান ", যা অনুবাদ করে 0xB02A
( 0xB0
অপকড 0x2A
হওয়ায়, "তাত্ক্ষণিক" যুক্তি হয়ে)। সুতরাং যে দুটি বাইট লাগে।
- এর জন্য কোনও শর্টকাট অপকোড নেই
mov al, al
(যেহেতু এটি মূলত করণীয় একটি মূ .় কাজ), সুতরাং আপনাকে mov al, rmb
(আরবিএম হ'ল "রেজিস্টার বা স্মৃতি") ওভারলোড ব্যবহার করতে হবে। এটি আসলে তিন বাইট লাগে । (যদিও এটি সম্ভবত এর mov rb, rmb
পরিবর্তে কম নির্দিষ্ট ব্যবহার করবে, যার জন্য কেবল দুটি বাইট নেওয়া উচিত mov al, al
- আর্গুমেন্ট বাইটটি উত্স এবং লক্ষ্য রেজিস্ট্রার উভয়ই নির্দিষ্ট করতে ব্যবহৃত হয়; এখন আপনি জানেন যে কেন ৮৮86৮ টিতে কেবল ৮ টি রেজিস্টার ছিল: ডি)। তুলনা করুন NOP
, যা আ সিঙ্গল বাইট নির্দেশ! এটি মেমরি এবং সময় সাশ্রয় করে, যেহেতু ৮০৮৮ সালে মেমোরিটি পড়া এখনও বেশ ব্যয়বহুল - অবশ্যই কোনও প্রোগ্রামটি কোনও টেপ বা ফ্লপি বা অন্য কিছু থেকে লোড করার কথা বলা উচিত নয়।
তাহলে xchg ax, ax
কোথা থেকে আসে? আপনাকে কেবল অন্যান্য xhcg
নির্দেশাবলীর অপকডগুলি দেখতে হবে । আপনি দেখতে পাবেন 0x86
, 0x87
এবং শেষ পর্যন্ত 0x91
- 0x97
। সুতরাং nop
এটির জন্য এটি 0x90
বেশ ভাল ফিটের মতো বলে মনে হচ্ছে xchg ax, ax
(যা আবার কোনও xchg
"ওভারলোড" নয় - আপনাকে xchg rb, rmb
দুটি বাইটে ব্যবহার করতে হবে )। এবং প্রকৃতপক্ষে, আমি খুব নিশ্চিত যে এটি সেই সময়ের মাইক্রো-আর্কিটেকচারের একটি দুর্দান্ত পার্শ্ব-প্রতিক্রিয়া ছিল - যদি আমি সঠিকভাবে স্মরণ করি তবে 0x90-0x97
"এক্সসিজিজি, রেজিস্টারগুলির উপরে অভিনয় ax
এবং ax
- di
" এর পুরো পরিসীমাটি ম্যাপ করা সহজ ছিল ( অপারেণ্ডটি প্রতিসাম্যহীন হওয়ায় এটি আপনাকে নাপ সহ পুরো পরিসর দেয় xchg ax, ax
; লক্ষ্য করুন যে আদেশটি রয়েছে ax, cx, dx, bx, sp, bp, si, di
- bx
পরে রয়েছে dx
,ax
; মনে রাখবেন, নিবন্ধের নামগুলি স্মৃতিবিজ্ঞান, অর্ডার করা নাম নয় - সংগ্রহকারী, কাউন্টার, ডেটা, বেস, স্ট্যাক পয়েন্টার, বেস পয়েন্টার, উত্স সূচক, গন্তব্য সূচক)। একই পদ্ধতিটি অন্যান্য অপারেটরগুলির জন্যও ব্যবহৃত হয়েছিল, উদাহরণস্বরূপ mov someRegister, immediate
সেট। একটি উপায়ে, আপনি এটিকে ভাবতে পারেন যেমন ওপকোডটি আসলে একটি পূর্ণ বাইট না - শেষ কয়েকটি বিটগুলি "আসল" অপারেন্ডের "যুক্তি"।
এই সব বলেছিল, x86-এ, nop
সম্ভবত একটি বাস্তব নির্দেশ হিসাবে বিবেচিত হবে, না। আসল মাইক্রো-আর্কিটেকচার এটিকে বৈকল্পিক হিসাবে বিবেচনা করে xchg
আমি যদি সঠিকভাবে স্মরণ করি তবে এটি nop
নির্দিষ্টকরণে আসলে নামকরণ করা হয়েছিল। এবং যেহেতু xchg ax, ax
কোনও নির্দেশনা সত্যই বোঝায় না, তাই আপনি দেখতে পাচ্ছেন 0x90
যে ৮০ design of এর ডিজাইনাররা ট্রানজিস্টর এবং পথনির্দেশগুলিতে নির্দেশকে ডিকোডিংয়ে কীভাবে সংরক্ষণ করেছেন যে প্রাকৃতিকভাবে "নোপি" এমন কোনও স্থানে মানচিত্রটি ব্যবহার করে ।
অন্যদিকে, i8051 nop
- এর জন্য সম্পূর্ণ ডিজাইন-ইন অপকড রয়েছে 0x00
। কিন্ডা ব্যবহারিক। নির্দেশ নকশা মূলত অপারেশন জন্য উচ্চ মৃদু কামড় এবং operands নির্বাচনের জন্য কম মৃদু কামড় ব্যবহার করছে - উদাহরণস্বরূপ, add a
হয় 0x2Y
, এবং 0xX8
মানে হলো "রেজিস্টার করো 0 সরাসরি" তে, তাই 0x28
হয় add a, r0
। সিলিকনে অনেক সঞ্চয় করে :)
আমি তখনও যেতে পারলাম, যেহেতু সিপিইউ ডিজাইন (সংকলক নকশা এবং ভাষার নকশার উল্লেখ না করা) বেশ বিস্তৃত বিষয়, তবে আমি মনে করি যে আমি অনেকগুলি ভিন্ন দৃষ্টিভঙ্গি প্রদর্শন করেছি যা ডিজাইনের মতো রয়েছে বেশ সুন্দরভাবে।