x86-64 মেশিন কোড, 8 বাইট
ব্রুস ফোর্টের সমাধান থেকে অনুপ্রাণিত , তবে সামান্য সামান্য নীচে। :-)
8D 07 lea eax, [rdi] ; put copy of input parameter in EAX
D1 EF shr edi, 1 ; shift LSB into CF
InfiniteLoop:
F3 73 FD rep jnc InfiniteLoop ; test CF; infinite loop back here if input was even
C3 ret ; return with original input in EAX if it was odd
একটি একক পূর্ণসংখ্যা পরামিতি নেওয়া হয় EDI
সিস্টেম ভিএমডি 64 কলিং কনভেনশন অনুসরণ করে রেজিস্টারে ।
প্রাথমিকভাবে এই মানটির একটি অনুলিপি তৈরি করা হয়েছে এবং EAX
এটি যথাযথভাবে ফিরিয়ে দেওয়া যেতে পারে। ( LEA
স্বাভাবিকের পরিবর্তে ব্যবহৃত হয়)MOV
কারণ আমাদের বিজোড় বাইট সহ একটি নির্দেশনা প্রয়োজন))
তারপরে, মানটি EDI
1 দ্বারা ডানদিকে স্থানান্তরিত হয় যা শিফিট-অফ বিটটিকে ক্যারি পতাকা (সিএফ) এ রাখে। সংখ্যাটি সমান হলে এই বিটটি 0 হবে বা বিজোড় হলে 1 হবে।
তারপরে আমরা JNC
নির্দেশ ব্যবহার করে সিএফ পরীক্ষা করি , যা কেবল সিএফ 0 হলে (যেমন, সংখ্যাটি সমান ছিল) কেবল শাখা করবে। এর অর্থ হ'ল আমরা এমনকি মানগুলির জন্য একটি অসীম লুপে যাব। বিজোড় মানগুলির জন্য, আমরা এর মধ্যে পড়ি এবং আসল মানটি (এর মধ্যে)EAX
) ফিরে আসে।
JNC
নির্দেশের সাথে কিছু কৌশল আছে , যদিও এটির REP
উপসর্গ রয়েছে! সাধারণত, REP
উপসর্গগুলি কেবল স্ট্রিং নির্দেশাবলীর সাথেই ব্যবহৃত হয় তবে ইনটেল এবং এএমডি ম্যানুয়াল উভয়ই সম্মত হয় যে অপ্রাসঙ্গিক / অতিশয় / অপ্রয়োজনীয় REP
উপসর্গগুলি উপেক্ষা করা হয়, তাই আমরা এটি 3 বাইট দীর্ঘ করতে শাখার নির্দেশে একটি নিক্ষেপ করি। এইভাবে, জাম্প নির্দেশে এনকোড হওয়া আপেক্ষিক অফসেটটিও বিজোড়। (এবং, অবশ্যই REP
এটি একটি বিজোড় বাইট উপসর্গ।)
শুভতা ধন্যবাদ RET
একটি বিজোড় বাইট ব্যবহার করে এনকোড করা হয়েছে!
এটি অনলাইন চেষ্টা করুন!
আপনি যদি ভাবছেন না যে মানটি বিজোড় হলে তা ফেরত দেওয়া বা এটি অসীম লুপের মধ্যে চলে যাওয়া (এমনকি আপনি কখনই ফিরে আসেন না) চ্যালেঞ্জের "আউটপুট" প্রয়োজনীয়তাগুলি পূরণ করে, বা আপনি আরও কিছু আকর্ষণীয় কিছু চান, এখানে একটি ফাংশন রয়েছে এটি সিরিয়াল পোর্টের মানকে আউটপুট করে (তবে এটি কেবল বিজোড় হলে অবশ্যই)।
x86-64 মেশিন কোড (সিরিয়াল পোর্টে আউটপুট), 17 বাইট
8D 07 lea eax, [rdi] ; put copy of input parameter (EDI) in EAX
B1 F7 mov cl, 0xf7 ; put 0xF7 into low-order bits of CX
B5 03 mov ch, 0x03 ; put 0x03 into high-order bits of CX
FE C1 inc cl ; increment low-order bits of CX to 0xF8 (so all together it's now 0x3F8)
0F B7 D1 movzx edx, cx ; move CX to DX ("MOV DX, CX" would have a 16-bit prefix of 0x66)
D1 EF shr edi, 1 ; shift LSB of input parameter into CF
73 01 jnc IsEven ; test CF: branch if 0 (even), fall through if 1 (odd)
EF out dx, eax ; output EAX (original input) to I/O port 0x3F8 (in DX)
IsEven:
C3 ret ; return
এটিকে কীটাকে আরও আকর্ষণীয় করে তোলে তা হ'ল কোডটি আরও বেশি করে , যার অর্থ কেবল বিজোড় বাইট ব্যবহার করে এনকোড করা নির্দেশাবলী ব্যবহার করে এটি করা সব থেকে বেশি চ্যালেঞ্জ ছিল। অবশ্যই এটিরও অর্থ এটি কোড গল্ফে ব্যর্থ হয়, সুতরাং এটি এক ধরণের ট্রেড অফ you আপনি আকর্ষণীয় এবং চ্যালেঞ্জিং চান বা আপনি সংক্ষিপ্ত চান?
যাইহোক, এটি আই / ও পোর্ট 0x3F8, যা একটি পিসির স্ট্যান্ডার্ড COM1 সিরিয়াল পোর্ট লিখতে x86 OUT
নির্দেশিকা ব্যবহার করে । মজাদার অংশটি অবশ্যই হ'ল সমস্ত স্ট্যান্ডার্ড আই / ও পোর্টগুলির (সিরিয়াল এবং সমান্তরাল) এমনকি ঠিকানাও রয়েছে, সুতরাং এগুলি কেবল নির্দেশের নকল হিসাবে এনকোড করা যায় না বা সরাসরি কোনও রেজিস্টারে স্থানান্তরিত করা যায় না। আপনাকে প্রকৃত মানের চেয়ে কম দিয়ে আরম্ভ করতে হবে এবং তারপরে বৃদ্ধিও হবেOUT
রেজিস্টারে মান করতে হবে। আপনি ম্যানিপুলেশনের জন্য নির্দিষ্ট কয়েকটি রেজিস্টার ব্যবহারের ক্ষেত্রেও সীমাবদ্ধ কারণ অপারেটর হিসাবে ব্যবহারের সময় নির্দেশিকায় বিজোড় বাইট ব্যবহার করে এনকোড করা আপনার নিবন্ধগুলি প্রয়োজন।
এছাড়াও, আমাকে লুপের শীর্ষে DX
রেজিস্টারটি (নিবন্ধকের মাধ্যমে CX
) আরম্ভ করতে হয়েছিল, যদিও মানটি বিজোড় হলে কেবল এটির প্রয়োজন হয়, যাতে JNC
নির্দেশটি একটি বিজোড় অফসেট পাবে তা নিশ্চিত করতে । তবে, যেহেতু আমরা যে বিষয়টি এড়িয়ে যাচ্ছি তা হ'ল OUT
নির্দেশনা, তাই এই সমস্ত কোডটি নষ্ট চক্র এবং ক্লোবার স্ক্র্যাচ নিবন্ধগুলি; এটি আসলে কিছুই আউটপুট দেয় না , সুতরাং এটি নিয়মগুলি ভঙ্গ করে না।
অবশেষে, এই ফাংশনটি সিরিয়াল পোর্টে আউটপুটটি সম্পন্ন বা না করে পরে ফিরে আসবে ইনপুট মানটি রেখে EAX
। কিন্তু এটি আসলে কোনও নিয়ম ভঙ্গ করে না; সমাবেশ ভাষায় সমস্ত ফাংশন একটি মান দিয়ে ফিরে আসবে EAX
- প্রশ্নটি কেবল এটি একটি উল্লেখযোগ্য মান বা আবর্জনা মূল্য। এটি ফাংশনের ডকুমেন্টেশন দ্বারা নির্ধারিত হয় (মূলত, এটি কোনও মান দেয় বা এটি ফিরে আসে)void
) এবং এই ক্ষেত্রে, আমি এটি কোনও মান ফেরত না হিসাবে ডকুমেন্ট করছি। :-)
এটির জন্য কোনও টিআইও লিঙ্ক নেই, কারণ এটি সিরিয়াল পোর্টগুলিতে আউটপুট বাস্তবায়ন করে না। আপনার আসল লোহা বা একটি কল্পনা দরকার।