স্ব-পরিবর্তনকারী কোড

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

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

কোডের এই পরিবর্তনগুলো নিন্মোক্ত সময়গুলোতে করা যায়ঃ

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

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

আইবিএম/৩৬০ এবং জেড/আর্কিটেকচারের ক্ষেত্রে, 'এক্সিকিউট' নির্দেশনাটি তার টার্গেট নির্দেশনাটির প্রথম রেজিস্টারের ৮ বিটের মধ্যে দ্বিতীয় বাইটটিকে যৌক্তিকভাবে পরিবর্তিত করে ফেলে। কিন্তু এই স্ব-পরিবর্তনের ফলে সংগ্রহস্থলের প্রকৃত নির্দেশনার কোন পরিবর্তন হয় না। 

লো এবং হাই লেভেল প্রোগ্রামিং ভাষায় এর ব্যবহারঃ সম্পাদনা

প্রোগ্রামিং ভাষার উপর ভিত্তি করে কোডের স্ব-পরিবর্তন বিভিন্নভাবে হতে পারে। এটি পয়েন্টারে পরিবর্তনশীল কম্পাইলার বা ইন্টারপ্রেটার ইঞ্জিনের সাহায্যেও হতে পারেঃ

  • পূর্ববর্তী নির্দেশনাবলী পরিবির্তিত করে ( অথবা নির্দেশনাবলী একটি অংশ যেমন অপকোড, রেজিস্টার, ফ্ল্যাগ বা অ্যাড্রেস) অথবা 
  • সরাসরি সম্পূর্ণ নির্দেশাবলী তৈরি করে অথবা মেমরিতে থাকা ক্রমানুযায়ী নির্দেশাবলী
  • সোর্স কোড তৈরি অথবা পরিমার্জন করে একটি 'মিনি কম্পাইলার' অথবা পরিবর্তনশীল ইন্টারপ্রেটার ব্যবহার করে 
  •  একটি সম্পূর্ণ পরিবর্তনশীল প্রোগ্রাম তৈরি করা এবং তারপর সেটি এক্সিকিউট করা

অ্যাসেম্বলি ভাষা সম্পাদনা

অ্যাসেম্বলি ভাষা ব্যবহার করে স্ব-পরিবর্তনশীল কোড বাস্তবায়ন করা মোটামুটি সহজ। এক্ষেত্রে নির্দেশনাগুলো মেমরিতে নতুন করে তৈরি করা যায় এবং এগুলো পরিবর্তনশীল। অথবা পূর্বের অসুরক্ষিত কোড মুছে ফেলেও আগের মেমরিতেই নতুন করে কোড করা যায়। উভয়ক্ষেত্রেই এমনভাবে কোড লিখতে হয়, যেন একটি সাধারণ কম্পাইলার সহজেই কোডটিকে অবজেক্ট কোড হিসাবে তৈরি করতে পারে। এক্ষেত্রে আধুনিক প্রসেসর ব্যবহার করা হলে, সেখানে সিপিইউ ক্যাশে কিছু অনিচ্ছাকৃত পার্শ্ব প্রতিক্রিয়া হতে পারে। এই পদ্ধতিটি অ্যাসেম্বলি ভাষায় লিখা কোডের প্রথম শর্তটি পরীক্ষা করার জন্য বেশি ব্যবহার করা হয়। এর একটি উৎকৃষ্ট উদাহরণ হচ্ছে আইবিএম/৩৬০ এর অ্যাসেম্বলি ভাষা। অ্যাসেম্বলি ভাষায় স্ব-পরিবর্তনশীল কোড ব্যবহার করলে নির্দেশনাবলী পরিমান (N x 1)-1 সংখ্যক কমে। এখানে N হচ্ছে ফাইলে রেকর্ডের সংখ্যা। (পূর্বের অসুরক্ষিত কোড মুছে ফেলে নতুন কোড লিখার কারণে -1 ব্যবহার করা হয়েছে)।

SUBRTN NOP OPENED      FIRST TIME HERE?
* The NOP is x'4700'<Address_of_opened>
       OI    SUBRTN+1,X'F0'  YES, CHANGE NOP TO UNCONDITIONAL BRANCH (47F0...)
       OPEN   INPUT               AND  OPEN THE INPUT FILE SINCE IT'S THE FIRST TIME THRU
OPENED GET    INPUT        NORMAL PROCESSING RESUMES HERE
      ...

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

হাই লেভেল প্রোগ্রামিং ভাষা সম্পাদনা

কিছু প্রোগ্রামিং ভাষায় স্পষ্টভাবে স্ব-পরিবর্তনকারী কোড সমর্থন করে। উদাহরণস্বরূপ, ব্যবসায়িক কাজে ব্যবহৃত এক বিশেষ ধরনের কম্পিউটার ভাষা, কোবোলে কোড এক্সিকিউট হওয়ার সময় স্ব-পরিবর্তনকারী কোড কাজ করতে পারে।[১] এক-ব্যাচ প্রোগ্রামিং ভাষায় স্ব-পরিবর্তনকারী কোড ব্যবহার করতে হয়।[২] এছাড়াও 'ক্লিপার' এবং 'এসপিআইটিবিওএল' প্রোগ্রামিং ভাষাগুলোও সরাসরি স্ব-পরিবর্তনকারী কোডের সুবিধা প্রদান করে। বি৬৭০০ সিস্টেমে ব্যবহৃত অ্যালগল কম্পাইলার কোড এক্সিকিউট হওয়ার সময় টেক্সট স্ট্রিং চালনা করতে পারে এবং পরে আবার সেটিকে প্রয়োজন হলে পুনরায় ডেকে ব্যবহারও করতে পারে। 

কিছু কিছু প্রোগ্রামিং ভাষায় মেশিন কোডই হচ্ছে সোর্স কোড এবং এই কোড সবসময়ই পরিবর্তন করা যায়। স্নোবল প্রোগ্রামিং ভাষায় সোর্স কোড একটি টেক্সট অ্যারে এর উপাদান হিসিবে এক্সিকিউট হয়। অন্যান্য প্রোগ্রামিং ভাষা যেমন পার্ল এবং পাইথনে প্রোগ্রামগুলো রান-টাইমে 'ইভাল' ফাংশন ব্যবহার করে নতুন কোড তৈরি করতে পারে, কিন্তু পূর্বের কোডে কোনরূপ পরিবর্তন করতে পারে না। এই পরিবর্তন বিষয়ক বিভ্রমটি (এমনকি মেশিন কোডও মূলত বদলানো হয়না) ফাংশন পয়েন্টারে পরিবর্তন করার কারণে ঘটে থাকে। নিচের জাভাস্ক্রিপ্টের উদাহরণটি লক্ষ্য করা যাকঃ

    var f = function (x) {return x + 1};

    // assign a new definition to f:
    f = new Function('x', 'return x + 2');

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

প্যুশ প্রোগ্রামিং ভাষা এমন একটি প্রোগ্রামিং ভাষা, যেটি সহজে স্ব-পরিবর্তনকারী কোড ব্যবহার করার জন্য তৈরি করা হয়েছে। এটি কোন উচ্চ স্তরের প্রোগ্রামিং ভাষা নয়, কিন্তু অ্যাসেম্বলি ভাষার মত নিন্ম স্তরেরও নয়।[৩]

চক্রবৃদ্ধি পরিবর্তন সম্পাদনা

একাধিক উইন্ডোজ সিস্টেম আসার আগে, কমান্ড-লাইন সিস্টেমে একটি মেন্যু সিস্টেম থাকতো, যার সাহায্যে রানিং কমান্ডের কোড পরিবর্তন করার সুযোগ ছিল। মনে করুন, একটি ডিওএস স্ক্রিপ্ট ফাইল Menu.bat তে নিচের কোডগুলো থাকতে পারেঃ

   :StartAfresh                <-A line starting with a colon marks a label.
   ShowMenu.exe

Menu.bat অপারেশনটি কমান্ড-লাইন থেকে চালানোর পর কোডে থাকা ShowMenu লাইনটি কম্পিউটারের স্ক্রিনে একটি মেন্যু নিয়ে আসে, যেখানে ব্যবহারকারীকে সাহায্য করার জন্য প্রয়োজনীয় তথ্য, উদাহরণ এবং অন্যান্য তথ্য থাকে। এমনকি ব্যবহারকারী এমন কোডও নির্বাচন করতে পারেন, যেখানে somename নামক কমান্ড চালনা করলে ShowMenu কমান্ডটি কাজ করবে। ShowMenu কোডটি যখন Menu.bat ফাইলে নিচের মত করে পুনরায় লিখা হবে, তখন ShowMenu কোডটির কাজ শেষ হয়ে যাবে

   :StartAfresh
   ShowMenu.exe
   CALL C:\Commands\somename.bat
   GOTO StartAfresh

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

যখন অন্য কমান্ডগুলো কাজ শুরু করে, তখন ShowMenu.exe সিস্টেমটি মেমরিতে থাকেনা। এতে অনেক মেমরি বেঁচে যায়। অর্থাৎ, বলা যায় একটি মেন্যু সিস্টেম(এবং সাথে আরও সম্ভাব্য সাহায্যকারী ফিচার) থাকার সুবিধার পাশাপাশি, যদি ব্যবহারকারীর মেমরির সাইজ কম থাকে, তাহলে এই পদ্ধতিটি অনেক উপকারীও বটে। 

কন্ট্রোল টেবিল সম্পাদনা

কন্ট্রোল টেবিল ইন্টারপ্রেটার বলতে বুঝায় যেটি নিজে নিজে টেবিল থেকে তথ্য নিয়ে কাজ করতে পারে। (বরং বিশেষভাবে বলা যায়, শর্তযুক্ত নির্দেশ যেমন "IF inputx = 'yyy'" এর মত নয়)।

ইতিহাস সম্পাদনা

১৯৪৮ সালের জানুয়ারীতে প্রকাশিত হওয়া আইবিএম এসএসইসি কম্পিউটারটির নিজে নিজে এর নির্দেশনাবলী নিয়ে কাজ করতে সমর্থ্য ছিল। এছাড়া এটি এর নির্দেশনাবলীকে তথ্য হিসেবেও ব্যবহার করতে পারতো। যাইহোক, এই সামর্থ্যটি বাস্তবে খুব কমই ব্যবহার করা হয়েছিল।[৪] স্ব-পরিবর্তনকারী কোড আবিষ্কার হওয়ার প্রথম দিকে এটি প্রায়ই কম মেমরির ব্যবহার এবং কোড যাতে দ্রুত কাজ করে সেই উদ্দেশ্যে কিংবা উভয় উদ্দেশ্যে ব্যবহার করা হত। এছাড়াও সাবরুটিন নিয়ে কাজ করতে এবং যখন নির্দেশনাবলীতে কোডের কোন সাধারণ শাখা বা বাদ দেয়ার মত কোন কোড থাকতো, তখনও স্ব-পরিবর্তনকারী কোড ব্যাপকভাবে ব্যবহার করা হত। এই ব্যবহারটি এখনও অন্তত তত্ত্বগতভাবে হলেও আলট্রা-আরআইএসসি আর্কিটেকচারে ব্যবহৃত হচ্ছে। ডোনাল্ড কানুথের এমআইএক্স কম্পিউটারেও সাবরুটিন নিয়ে কাজ করার জন্য স্ব-পরিবর্তনকারী কোড ব্যবহার করা হয়।

ব্যবহার সম্পাদনা

স্ব-পরিবর্তনকারী কোড বিভিন্ন উদ্দেশ্যে ব্যবহার করা যেতে পারে। যেমনঃ

  • একটি অনির্ভরশীল লুপকে আধা-স্বয়ংক্রিয় করা যায়।
  • রানটাইম অথবা লোডটাইমে কোড পরিবর্তন বা পরিমার্জন করা যায়। এই সুবিধাটির জন্যই স্ব-পরিবর্তনকারী কোড সবচেয়ে বেশি জনপ্রিয়।
  • অবজেক্টের ইনলাইন স্টেট পরিবর্তন করা অথবা ক্লোজারের উচ্চ স্তরের কাজ সহজে করা যায়।
  • সাবরুটিনের অ্যাড্রেস একত্র করার জন্য ব্যবহার করা হয়। মূলত একটি কোডের লাইব্রেরী ফাংশন যখন কাজ করে কিংবা কাজ করা শুরু করে, তখন এটি কাজ করে। অথবা এটি প্রত্যেকবার সাবরুটিনের অভ্যন্তরীণ রেফারেন্সগুলোকে একত্র করে যাতে করে তাদের আসল অ্যাড্রেস ব্যবহার করা যায়। (উদাহরণস্বরূপ পরোক্ষ 'স্ব-পরিমার্জন')।
  • কম্পিউটিং সিস্টেমের বিবর্তন। যেমন জেনেটিক প্রোগ্রামিং।
  • ডিবাগার অথবা ডিঅ্যাসেম্বলার ব্যবহার করে ডিবাগিং এর সাহায্যে লুকানো কোড বের করতে ব্যবহৃত হয়। এছাড়াও বিভিন্ন সফটওয়ারের ভাইরাস বা স্পাইওয়ার খুঁজে বের করার জন্য স্ব-পরিবর্তনকারী কোড ব্যবহার করা হয়।
  • কিছু কিছু আর্কিটেকচারে ১০০% মেমোরি ব্যবহারের নিশ্চয়তা দেয়। এটি সাধারণত একটি ঘূর্ণায়মান প্যাটার্নের সাহায্যে অপকোডের পুনরাবৃত্তি অথবা সকল প্রোগ্রাম বা তথ্য মুছে ফেলা কিংবা হার্ডওয়ারের সাহায্যে করা হয়ে থাকে। 
  • যখন মেমরি বা ডিস্কে জায়গা কম থাকে, তখন কোডকে সংকুচিত করে রানটাইমে কোড এক্সিকিউট করার জন্য ব্যবহৃত হয়। 
  • কিছু কিছু ফাংশন আছে, যেগুলো স্ব-পরিবর্তনকারী কোড ব্যতীত কিছুতেই কাজ করেনা। উদাহরণস্বরূপ, একটি 'এক নির্দেশ সেট কম্পিউটার (ওআইএসসি)' যেটি কেবল বিয়োগ,এবং,শাখা,যদি অ ঋণাত্মক নির্দেশনাবলী নিয়ে কাজ করে, তারা সেখানে স্ব-পরিবর্তনকারী কোড ব্যবহার করা ছাড়া কিছুতেই করা যাবে না। উদাহরণস্বরূপ,সি প্রোগ্রামিং ভাষায় "*a = **b" এর সমতুল্য। 
  • কোডের ভুল ঠিক করার জন্য নির্দেশনাবলীর পরিবর্তনকারী হিসেবে ব্যবহৃত হয়।[৫]

স্টেট-নির্ভরশীল লুপ অপ্টিমাইজ সম্পাদনা

স্টেট-নির্ভরশীল লুপ অপ্টিমাইজের একটি জেনারেল ফর্ম নিচে দেয়া হল:

repeat N times {
   if STATE is 1
      increase A by one
   else
      decrease A by one
   do something with A
}

এইক্ষেত্রে স্ব-পরিবর্তনকারী কোড করার জন্য নিচের মত করে লুপটিকে একটু পরিবর্তন করে লিখলেই সমস্যাটির সমাধান হয়ে যায় :

 repeat N times {
    increase A by one
    do something with A
    when STATE has to switch {
       replace the opcode "increase" above with the opcode to decrease, or vice versa
    }
 }

এখানে উল্লেখ্য যে, উপরের কোডে অপকোডের প্রতিস্থাপনটি এভাবে সহজে লিখা যায়, 'এক্সওআর ভ্যারিয়েবল অ্যাড্রেস হবে "অপকোড অফ(আইএনসি) এক্সওআর অপকোড অফ(ডেসিমাল)"'।

এই সমাধানটি ব্যবহার করা হবে কিনা সেটি 'এন' এর মান এবং ফ্রিকুয়েন্সির পরিবর্তনের উপর নির্ভর করে। 

বিশেষীকরণ সম্পাদনা

মনে করুন, পরিসংখ্যানের একটি সেট অনেক বেশি তথ্য উপাত্ত দিয়ে হিসাব করা হবে। যেখানে গড়, এক্সট্রিমা, এক্সট্রিমার অবস্থান, স্ট্যানডার্ড ডেভিয়েশন ইত্যাদি থাকবে। সাধারণ অবস্থায় সেখানে ডেটা এবং ওয়েট যুক্ত করার অপশন থাকবে। সুতরাং প্রতিটি  xi, wi এর সাথে যুক্ত হবে এবং প্রতিটি ইনডেক্সে ওয়েট থাকলে সেখানে হিসাবটি দুটি নিয়মে হতে পারে। একটি নিয়ম হচ্ছে ওয়েট ব্যবহার করে এবং অপরটি হচ্ছে ওয়েট ব্যবহার ছাড়া।  এখন আরও একটি নিয়ম বিবেচনা করা যাক, ইনডেক্সের প্রতিটি মানই একটি সম্ভাব্য বুলিয়ান মানের সাথে যুক্ত আছে যাতে করে সেটা নিশ্চিত করা যায় যে, মানটি নিয়ে কাজ করা হবে নাকি হবে না। এই কোডটি চারটি ব্যাচে নিয়ন্ত্রণ করা যায়, এর একটি হচ্ছে উৎপাদক দ্বারা কোডটির ফলাফল বের করা এবং এই পদ্ধতিতে কোডের আকার বৃদ্ধি পাবে। অথবা, আরও একটি উপায় হল যে অ্যারেগুলো এড়িয়ে যাওয়া হয়েছিল সেগুলো এবং তাদের ওয়েট একত্রে যুক্ত করে একটি সাময়িক অ্যারেতে রাখা। এখানেও কোড কাজ করার সময় কোডের আকার বৃদ্ধি পাবে। যাইহোক, এভাবে কোড সামান্য পরিবর্তন করে পরিসংখ্যানের হিসাব করা হলে সেখানে অপ্রয়োজনীয় মানগুলো আর থাকবে না এবং কোডও সম্পূর্ণ সঠিক হবে। এখানে কোন মান দ্বিতীয়বার যাচাই করা হবে না এবং ডেটা অ্যারে কেবলমাত্র একবারই চেক করা হবে।

ছদ্মবেশ হিসাবে ব্যবহার সম্পাদনা

১৯৮০ সালে অ্যাপল ২ এবং আইবিএম পিসিতে ডিস্কের উপর ভিত্তি করে বানানো প্রোগ্রামগুলোতে কোড যাতে কেউ নকল করতে না পারে, সেজন্য স্ব-পরিবর্তনকারী কোড ব্যবহার করা হত। উদাহরণস্বরূপ, একটি আইবিএম পিসিতে থাকা ফ্লপি ডিস্কে 'int 0x13' নামক কোড থাকতো যেটি প্রোগ্রামের তালিকায় দেখাতো না। কিন্তু এই কোডটি মেমরিতে থাকতো এবং স্বনিয়ন্ত্রিত ভাবে এই প্রোগ্রামটি কাজ করা শুরু করত। 

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

স্ব-উল্লেখ মেশিন লার্নিং সিস্টেম সম্পাদনা

গতানুগতিক মেশিন লার্নিং সিস্টেমে সাধারণত একটি নির্দিষ্ট এবং পূর্বে প্রোগ্রাম করা অ্যালগরিদম ব্যবহার করা হয়। অতঃপর ১৯৮০ সালে জর্জেন স্কিম্বার বেশ কয়েকটি স্ব-পরিবর্তনকারী কোডের নিয়ম আবিষ্কার করেন যেগুলো নিজে নিজেই তাদের নিজস্ব অ্যালগরিদমে পরিবর্তন ঘটাতে পারতো। এমনকি এটি কোডের জন্য বিপদজনক যেকোনো কোডের ব্যাপারে সতর্ক ছিল এবং যেকোনো প্রকার বিপদজনক কোড সহজেই মুছে ফেলতে পারতো। কোডের এই স্ব-পরিমার্জন এই বিষয়টি নিশ্চিত করে যে, ব্যবহারকারী যদি সঠিকভাবে ফিটনেস, এরর অথবা রিওয়ার্ড ফাংশন ব্যবহার করে কেবলমাত্র তাহলেই কোডে স্ব-পরিমার্জন ঘটবে।

অপারেটিং সিস্টেম সম্পাদনা

যেহেতু কোডে স্ব-পরিমার্জনের ফলে কম্পিউটারের নিরাপত্তা বিঘ্নিত হওয়ার সম্ভাবনা থাকে, সুতরাং প্রায় সকল অপারেটিং সিস্টেমেই স্ব-পরিবর্তনকারী কোড পাওয়ামাত্রই সেটি মুছে দেয়। কোডটির নিজে থেকে  স্ব-পরিমার্জন বৈশিষ্ট্য থাকার জন্য নয়, বরং এই কোডটি কম্পিউটারের ক্ষতি করার সম্ভাবনা থাকে বলেই অপারেটিং সিস্টেম কোডটি মুছে দেয়।

এর ফলে কম্পিউটারে অনেক সমস্যা হতে পারে। সুতরাং এই সমস্যাটি সমাধান করার জন্য অপারেটিং সিস্টেমগুলো নতুন একটি ফিচার তৈরি করে। এর নাম দেয়া হয়  W^X ("রাইট এক্সওআর এক্সিকিউট" করার জন্য)। এটি মূলত ঐ সকল প্রোগ্রামগুলোকে কাজ করতে বাধা দেয়, যেগুলো স্ব-পরিবর্তনকারী কোড ব্যবহার করার সময় কোডে কোনরূপ পরিবর্তন করে।  কোন প্রোগ্রামে যদি কোড পরিবর্তনের ব্যাপারটি নিষেধ না থাকে, তাহলেই কিছু কিছু অপারেটিং সিস্টেম সরাসরি ঐ প্রোগ্রামটি এক্সিকিউট করতে বাধা দেয়। অন্যান্য অপারেটিং সিস্টেমগুলোতে 'ব্যাক ডোর' নামক অপশন থাকে, যার মাধ্যমে বিভিন্ন প্রোগ্রামে দেওয়া পারমিশন সম্পর্কে সিস্টেম অবহিত থাকে। এই W^X ফিচারটি এড়িয়ে যাওয়ার সবচেয়ে সহজ উপায় হল সকল পারমিশন দিয়ে একটি ফাইল তৈরি করা এবং তারপর সেটি মেমরিতে দুইবার রাখা। লিনাক্সে এটি ছাড়াও কেউ ইচ্ছা করলে একটি অনথিভুক্ত সিসভি মেমোরি ফ্ল্যাগ তৈরি করেও এই ফিচারটি সহজে এড়িয়ে যাওয়া যায়। এই পদ্ধতিটি ব্যবহার করলে নতুন কোন ফাইল তৈরী করতে হয়না। 

এছাড়াও কম্পিউটার পলিমরফিজম ব্যবহার করে প্রোগ্রামের সর্বত্র ব্যবহার করা নিজস্ব ডেটা পরিবর্তন করেও প্রোগ্রামের কর্মপদ্ধতি নিজে নিজেই পরিবর্তন করতে পারে। 

ক্যাশ এবং স্ব-পরিবর্তনকারী কোডের মিথষ্ক্রিয়া সম্পাদনা

আর্কিটেকচারে ডেটা এবং নির্দেশ মিলিত হয়ে ক্যাশে জমা হয় এবং এই মিথষ্ক্রিয়া করার জন্য ক্যাশ সিঙ্ক্রোনাইজেশন অবশ্যই পরিবর্তিত কোড দ্বারা সঞ্চালিত করতে হবে। 

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

আধুনিক প্রসেসরের ক্যাশ বিষয়ক  এই সমস্যাটি তখনই সমাধান হবে, যখন স্ব-পরিবর্তনশীল কোডগুলো তাদের কোড খুব কম সময় পরিবর্তন করে। যেমন, ইনার লুপের ভিতরে যেভাবে লুপ পরিবর্তন হয় সেভাবে। [তথ্যসূত্র প্রয়োজন]

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

ম্যাসালিন এর সংশ্লেষণ কার্নেল সম্পাদনা

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

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

পল হাবার্লি এবং ব্রুস কার্শ স্ব-পরিবর্তনশীল কোডের প্রান্তিকীকরণের বিরোধিতা করেন। তাদের মতে এতে করে বিভিন্ন অপারেটিং সিস্টেম অথবা প্রোগ্রাম তৈরিতে খরচের পরিমান বৃদ্ধি পাবে।[তথ্যসূত্র প্রয়োজন]

সুবিধাসমূহ সম্পাদনা

  • স্ব-পরিবর্তনশীল কোড ব্যবহার করে সহজেই বিভিন্ন প্রোগ্রাম এক্সিকিউট করা যায়, এতে করে পুনরাবৃত্তিপূর্ণ এবং শর্তযুক্ত কোডের পরিমান কমে যায়।
  • স্ব-পরিবর্তনশীল কোড আলগোরিদিমিক দক্ষতা আরও উন্নত করতে পারে।

অসুবিধাসমূহ সম্পাদনা

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

স্ব-পরিবর্তনশীল কোড এমনভাবেও লিখা যায়, যেখানে এটি কোডের বিভিন্ন ফ্ল্যাগ এবং শাখা পরখ করে দেখে যে কীভাবে কোডটি এক্সিকিউট করলে সহজে ফলাফল আসবে। এতে করে সময় লাগে একটু বেশি। কিন্তু তুলনামুলকভাবে স্ব-পরিবর্তনশীল কোড দ্রুত কাজ করে।

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

স্ব-পরিবর্তনশীল কোড সবসময় ব্যবহার করা যায় না। যেসকল অবস্থায় স্ব-পরিবর্তনশীল কোড ব্যবহার করা যায় না, সেগুলো নিচে দেয়া হল:

  • যেসকল অ্যাপ্লিকেশন সফটওয়ার এমন অপারেটিং সিস্টেমে চলে যেখানে শক্তিশালী W^X নিরাপত্তা ব্যবহার করা হয়, সেখানে কিছুতেই স্ব-পরিবর্তনশীল কোড কাজ করেনা। এই সকল অপারেটিং সিস্টেমগুলো কেবল মেমরিতে কোড পরিবর্তন করতে পারে। কোড কাজ করা শুরু করলে আর কোডের নির্দেশনাবলী পরিবর্তন করতে পারেনা। 
  • হার্ভার্ডে তৈরি হওয়া অনেক মাইক্রোকন্ট্রোলারে স্ব-পরিবর্তনশীল কোডের নির্দেশনাবলী কাজ করেনা। সেখানে কেবল রম অথবা যেসকল মেমোরি স্বয়ংক্রিয় নয়, সেখানে কোড রাখতে পারে। 
  • যদি কোন প্রোগ্রাম স্ব-পরিবর্তনশীল কোড দিয়ে একাধিক কাজ একসাথে করতে চায়, তাহলে সেখানে কোন কাজ হয়না। উপরন্তু সেখানে কমপিউটেশন ভুল দেখায় অথবা সম্পূর্ণ অ্যাপ্লিকেশনটিই অকৃতকার্য হয়ে পড়ে।

আরও দেখুন সম্পাদনা

  • Algorithmic efficiency
  • eval statement
  • IBM 1130 (Example)
  • Just-in-time compilation: This technique can often give users many of the benefits of self-modifying code (except memory size) without the disadvantages.
  • Dynamic dead code elimination
  • PCASTL
  • Quine (computing)
  • Self-replication
  • Reflection (computer science)
  • Monkey patch: a modification to runtime code that does not affect a program's original source code
  • Extensible programming: a programming paradigm in which a programming language can modify its own syntax
  • কম্পিউটার ভাইরাস

তথ্যসূত্র সম্পাদনা

  1. "The ALTER Statement"। COBOL Language ReferenceMicro Focus 
  2. Self-modifying Batch File by Lars Fosdal
  3. "Push, PushGP, and Pushpop" 
  4. Bashe, C. J.; Buchholz, W.; Hawkins, G. V.; Ingram, J. J.; Rochester, N. (সেপ্টেম্বর ১৯৮১)। "The Architecture of IBM's Early Computers" (পিডিএফ)IBM Journal of System Development25 (5): 363–376। ডিওআই:10.1147/rd.255.0363সাইট সিয়ারX 10.1.1.93.8952 The SSEC was the first operating computer capable of treating its own stored instructions exactly like data, modifying them, and acting on the result. 
  5. "On Self-Modifying Code and the Space Shuttle OS – Carlos Enrique Ortiz"। ১৪ ফেব্রুয়ারি ২০১৭ তারিখে মূল থেকে আর্কাইভ করা। সংগ্রহের তারিখ ৩০ মার্চ ২০১৭ 

বহিঃসংযোগ সম্পাদনা