আমি এই সমালোচনামূলক বিভাগগুলির সাথে বেশ কয়েকটি সম্ভাব্য সমস্যা দেখছি। এই সমস্তগুলির জন্য সতর্কতা এবং সমাধান রয়েছে তবে সংক্ষিপ্তসার হিসাবে:
- অপ্টিমাইজেশান বা এলোমেলোভাবে অন্যান্য কারণে এই ম্যাক্রোগুলিতে কোড মুভিং থেকে কম্পাইলারকে প্রতিরোধ করার কিছুই নেই।
- তারা প্রসেসরের কিছু অংশ সংরক্ষণ এবং পুনরুদ্ধার করে বলে যে সংকলকটি ইনলাইন অ্যাসেমব্লিকে একা ছেড়ে চলে যাওয়ার প্রত্যাশা করে (যদি তা অন্যথায় না বলা হয়)।
- ক্রমটির মাঝামাঝি সময়ে বাধা পড়ার সময় এবং কখন এটি লেখা হয় তার মধ্যে রাষ্ট্র পরিবর্তন করা বাধা দেওয়ার কিছুই নেই।
প্রথমে, আপনার অবশ্যই কিছু সংকলক মেমরি বাধা দরকার । জিসিসি এগুলি ক্লোবার হিসাবে প্রয়োগ করে । মূলত, এটি সংকলককে বলার একটি উপায় "না, আপনি ইনলাইন অ্যাসেমব্লিকে এই অংশে মেমরি অ্যাক্সেসগুলি সরাতে পারবেন না কারণ এটি মেমরির অ্যাক্সেসের ফলাফলকে প্রভাবিত করতে পারে।" বিশেষত, আপনার আরম্ভ এবং শেষ ম্যাক্রো উভয়ের জন্য উভয় "memory"
এবং "cc"
ক্লোবার প্রয়োজন । এগুলি অন্যান্য জিনিসগুলিকে (যেমন ফাংশন কলগুলি) ইনলাইন অ্যাসেমব্লির তুলনায় পুনরায় অর্ডার করতে বাধা দেবে, কারণ সংকলক জানে যে তাদের মেমরির অ্যাক্সেস থাকতে পারে। আমি এআরএমের জিসিসি দেখতে পেয়েছি শর্ত কোড অবস্থায় "memory"
ক্লোবারের সাথে ইনলাইন অ্যাসেমব্লিতে রেজিস্ট্রেশন করা হয়েছে, সুতরাং আপনার অবশ্যই ক্লোবারের প্রয়োজন নেই "cc"
।
দ্বিতীয়ত, এই সমালোচনামূলক বিভাগগুলি বিঘ্ন সক্ষম করা সক্ষম করা আছে তার চেয়ে অনেক বেশি সঞ্চয় এবং পুনরুদ্ধার করছে। বিশেষত, তারা বেশিরভাগ সিপিএসআর সংরক্ষণ এবং পুনরুদ্ধার করছেন (বর্তমান প্রোগ্রামের স্থিতি রেজিস্টার) (লিঙ্কটি কর্টেক্স-আর 4 এর জন্য কারণ আমি একটি এ 9 এর জন্য একটি সুন্দর চিত্র খুঁজে পাইনি, তবে এটি অভিন্ন হওয়া উচিত)। এখানে সূক্ষ্ম বিধিনিষেধ রয়েছে যার চারদিকে রাষ্ট্রের টুকরোগুলি আসলে সংশোধন করা যেতে পারে তবে এটি এখানে প্রয়োজনীয়তার চেয়ে বেশি।
অন্যান্য জিনিসের মধ্যে এটির মধ্যে শর্তের কোড অন্তর্ভুক্ত রয়েছে (যেখানে নির্দেশাবলীর ফলাফলগুলি cmp
সংরক্ষণ করা হয় যাতে পরবর্তী শর্তসাপেক্ষ নির্দেশাবলী ফলাফলটিতে কাজ করতে পারে)। সংকলক অবশ্যই এটি দ্বারা বিভ্রান্ত হবে। এটি "cc"
উপরে উল্লিখিত হিসাবে ক্লোবার ব্যবহার করে সহজেই সমাধানযোগ্য । যাইহোক, এটি কোডটি প্রতিবার ব্যর্থ করে দেবে, তাই আপনি কী সমস্যার মুখোমুখি হচ্ছেন তা এমন শোনাচ্ছে না। কিছুটা টিকটিক টাইম বোম, যদিও এলোমেলোভাবে অন্যান্য কোড সংশোধন করে সংকলকটিকে কিছুটা আলাদা করার কারণ হতে পারে যা এটি দ্বারা ভেঙে যাবে।
এটি আইটি বিটগুলি সংরক্ষণ / পুনরুদ্ধার করার চেষ্টা করবে, যা থাম্ব শর্তযুক্ত বাস্তবায়ন বাস্তবায়নের জন্য ব্যবহৃত হয় । মনে রাখবেন যে আপনি যদি কখনও থাম্ব কোড প্রয়োগ করেন না তবে এটি কোনও বিষয় নয়। আমি কখনই বুঝতে পারি নি যে জিসিসির ইনলাইন অ্যাসেমব্লি আইটি বিটের সাথে কীভাবে কাজ করে, এটি শেষ না করে, অর্থাত সংকলকটি কখনই কোনও আইটি ব্লকে ইনলাইন অ্যাসেমবিলি স্থাপন করতে পারে না এবং সর্বদা আশা করে যে আইটি ব্লকের বাইরে সমাবেশটি শেষ হবে। আমি কখনই জিসিসি এই অনুমানগুলি লঙ্ঘনকারী কোড তৈরি করতে দেখিনি এবং ভারী অপ্টিমাইজেশান সহ আমি মোটামুটি জটিলতর ইনলাইন অ্যাসেমব্লি করেছি, সুতরাং আমি নিশ্চিতভাবে নিশ্চিত যে তারা তা ধরেছে। এর অর্থ সম্ভবত এটি সম্ভবত আইটি বিটগুলি পরিবর্তন করার চেষ্টা করবে না, সেক্ষেত্রে সবকিছু ঠিক আছে। এই বিটগুলি সংশোধন করার চেষ্টাকে "আর্কিটেকচারালি অপ্রত্যাশিত" হিসাবে শ্রেণিবদ্ধ করা হয়েছে, সুতরাং এটি সমস্ত ধরণের খারাপ কাজ করতে পারে তবে সম্ভবত কিছু করতে হবে না।
সর্বশেষ বিভাগের বিটগুলি যা সংরক্ষণ / পুনরুদ্ধার করা হবে (প্রকৃতপক্ষে বাধা নিষ্ক্রিয় করা ছাড়াও) মোড বিট। এগুলি সম্ভবত পরিবর্তিত হবে না, তাই এটি সম্ভবত কিছু যায় আসে না, তবে আপনার যদি এমন কোনও কোড থাকে যা ইচ্ছাকৃতভাবে মোডগুলি পরিবর্তন করে তবে এই বিঘ্নিত অংশগুলি সমস্যার কারণ হতে পারে। সুবিধাপ্রাপ্ত ও ব্যবহারকারী মোডের মধ্যে পরিবর্তন হ'ল এটি করার কেবলমাত্র আমি আশা করব।
তৃতীয়ত, সিপিএসআর এর অন্যান্য অংশগুলিকে MRS
এবং এর MSR
মধ্যে পরিবর্তন করতে বাধা দেওয়ার কিছুই নেই ARM_INT_LOCK
। এই জাতীয় কোনও পরিবর্তন ওভাররাইট করা যেতে পারে। বেশিরভাগ যুক্তিসঙ্গত সিস্টেমে, অ্যাসিঙ্ক্রোনাস বিঘ্নিত কোডগুলি (সিপিএসআর সহ) বিঘ্নিত হয় তার অবস্থার পরিবর্তন করে না। তারা যদি তা করে তবে কী কোড করবে তা নিয়ে যুক্তি করা খুব শক্ত হয়ে যায়। যাইহোক, এটি সম্ভব (FIQ অক্ষম বিট পরিবর্তন করা আমার কাছে বেশিরভাগ বলে মনে হয়), সুতরাং আপনার সিস্টেম এটি করে কিনা আপনার বিবেচনা করা উচিত।
আমি এগুলি কীভাবে এমনভাবে প্রয়োগ করব যা আমি নির্দেশিত সমস্ত সম্ভাব্য সমস্যাগুলির সমাধান করে:
#define ARM_INT_KEY_TYPE unsigned int
#define ARM_INT_LOCK(key_) \
asm volatile(\
"mrs %[key], cpsr\n\t"\
"ands %[key], %[key], #0xC0\n\t"\
"cpsid if\n\t" : [key]"=r"(key_) :: "memory", "cc" );
#define ARM_INT_UNLOCK(key_) asm volatile (\
"tst %[key], #0x40\n\t"\
"beq 0f\n\t"\
"cpsie f\n\t"\
"0: tst %[key], #0x80\n\t"\
"beq 1f\n\t"\
"cpsie i\n\t"
"1:\n\t" :: [key]"r" (key_) : "memory", "cc")
-mcpu=cortex-a9
কমপ্লেক্স নিশ্চিত করে নিন কারণ কমপক্ষে কিছু জিসিসি সংস্করণ (আমার মতো) পুরানো এআরএম সিপিইউতে ডিফল্ট রয়েছে যা সমর্থন করে না cpsie
এবং cpsid
।
আমি ব্যবহৃত ands
মাত্র পরিবর্তে and
মধ্যে ARM_INT_LOCK
তাই এটি একটি 16 বিট নির্দেশ যদি এই বুড়ো আঙ্গুলের কোড ব্যবহার করা হয় না। "cc"
ক্লোবারটি যে কোনওভাবেই প্রয়োজনীয়, সুতরাং এটি কঠোরভাবে পারফরম্যান্স / কোড আকারের বেনিফিট।
0
এবং 1
হয় স্থানীয় লেবেল , রেফারেন্স জন্য।
এগুলি আপনার সংস্করণগুলির মতো সমস্ত উপায়ে ব্যবহারযোগ্য হবে। ARM_INT_LOCK
ঠিক যেমন ফাস্ট / ছোট আপনার মূল এক হিসাবে হয়। দুর্ভাগ্যক্রমে, আমি খুব ARM_INT_UNLOCK
কম নির্দেশাবলী কাছাকাছি যে কোনও জায়গায় নিরাপদে করার উপায় নিয়ে আসতে পারিনি ।
যদি আইআরকিউ এবং এফআইকিউগুলি অক্ষম থাকে তখন আপনার সিস্টেমে বাধা রয়েছে, এটি সহজ করা যেতে পারে। উদাহরণস্বরূপ, যদি তারা সর্বদা একসাথে অক্ষম থাকে তবে আপনি এটির মতো cbz
+ একত্রিত করতে cpsie if
পারেন:
#define ARM_INT_UNLOCK(key_) asm volatile (\
"cbz %[key], 0f\n\t"\
"cpsie if\n\t"\
"0:\n\t" :: [key]"r" (key_) : "memory", "cc")
বিকল্পভাবে, আপনি যদি এফআইকিউগুলির বিষয়ে মোটেও চিন্তা করেন না তবে এটি কেবল তাদের সক্ষম / সম্পূর্ণভাবে অক্ষম করার জন্য ড্রপ করার অনুরূপ।
আপনি অন্য কিছুই জানেন তাহলে কি লক এবং আনলক মধ্যে CPSR অন্যান্য রাষ্ট্র বিট কোনো পরিবর্তন, তারপর আপনি ব্যবহার খুব আপনার মূল কোডে অনুরূপ কিছু দিয়ে অগ্রসর হতে পারে, উভয় সঙ্গে ব্যতীত "memory"
এবং "cc"
clobbers উভয় ARM_INT_LOCK
এবংARM_INT_UNLOCK