unsigned int fun1 ( unsigned int a, unsigned int b )
{
return(a+b);
}
unsigned char fun2 ( unsigned int a, unsigned int b )
{
return(a+b);
}
unsigned int fun3 ( unsigned char a, unsigned char b )
{
return(a+b);
}
unsigned char fun4 ( unsigned char a, unsigned char b )
{
return(a+b);
}
যেমনটি প্রত্যাশিত ফান 1 সমস্ত ইনটস তাই 16 বিট গণিত
00000000 <fun1>:
0: 86 0f add r24, r22
2: 97 1f adc r25, r23
4: 08 95 ret
যদিও প্রযুক্তিগতভাবে এটি ভুল হিসাবে কোড দ্বারা ডেকে আনা একটি 16 বিট সংযোজন ভুল, এমনকি অপ্রচলিত এই সংকলক ফলাফল আকারের কারণে অ্যাডসি অপসারণ করেছে।
00000006 <fun2>:
6: 86 0f add r24, r22
8: 08 95 ret
সত্যিকার অর্থে এখানে পদোন্নতি ঘটে না, কম্পাইলাররা এটি নিশ্চিত করে না যে সংস্করণটি কীভাবে এই সূচনাটি ঘটেছে, তা আমার কেরিয়ারের প্রথম দিকে চলে গিয়েছিল এবং সংযোজনকারীরা ক্রমবর্ধমান (যেমন উপরের মত) প্রচার করেও প্রচার করে নি, যদিও আমি প্রচার করি এটি উচার গণিত করতে বলেছিলেন, অবাক হন না।
0000000a <fun3>:
a: 70 e0 ldi r23, 0x00 ; 0
c: 26 2f mov r18, r22
e: 37 2f mov r19, r23
10: 28 0f add r18, r24
12: 31 1d adc r19, r1
14: 82 2f mov r24, r18
16: 93 2f mov r25, r19
18: 08 95 ret
এবং আদর্শ, আমি জানি এটি 8 বিট, একটি 8 বিট ফলাফল চাই তাই আমি কেবল এটি 8 বিটটি সারা পথ দিয়ে করতে বলেছি।
0000001a <fun4>:
1a: 86 0f add r24, r22
1c: 08 95 ret
সুতরাং সাধারণভাবে এটি নিবন্ধের আকারের জন্য লক্ষ্য করা ভাল, যা আদর্শভাবে একটি (ইউ) ইন্টের আকার, এর মতো একটি 8 বিট এমসিইউর জন্য সংকলক লেখককে একটি আপস করতে হয়েছিল ... পয়েন্টটি অভ্যাস তৈরি না করা গণিতের জন্য উচর ব্যবহার করে আপনি জানেন যে 8 টির বেশি বিটের দরকার নেই কারণ আপনি যখন সেই কোডটি সরান বা বড় রেজিস্টার সহ প্রসেসরে নতুন কোড লেখেন এখন সংকলকটির মুখোশ পড়া এবং প্রসারিত করতে হবে, যা কিছু স্থানীয়ভাবে কিছু নির্দেশাবলীতে করে থাকে, এবং অন্যরা না।
00000000 <fun1>:
0: e0800001 add r0, r0, r1
4: e12fff1e bx lr
00000008 <fun2>:
8: e0800001 add r0, r0, r1
c: e20000ff and r0, r0, #255 ; 0xff
10: e12fff1e bx lr
আরও 8 বিট খরচ জোর করা। আমি সামান্য / প্রচুর প্রতারণা করেছি, এটিকে আরও ন্যায্য উপায়ে দেখার জন্য আরও জটিল জটিল উদাহরণগুলির প্রয়োজন হবে।
মন্তব্য আলোচনার ভিত্তিতে ইডিটি
unsigned int fun ( unsigned char a, unsigned char b )
{
unsigned int c;
c = (a<<8)|b;
return(c);
}
00000000 <fun>:
0: 70 e0 ldi r23, 0x00 ; 0
2: 26 2f mov r18, r22
4: 37 2f mov r19, r23
6: 38 2b or r19, r24
8: 82 2f mov r24, r18
a: 93 2f mov r25, r19
c: 08 95 ret
00000000 <fun>:
0: e1810400 orr r0, r1, r0, lsl #8
4: e12fff1e bx lr
আকর্ষণ নেই. যদিও অপ্টিমাইজার কেন সেই অতিরিক্ত নির্দেশ রেখেছিল, আপনি কি আর 19 তে এলডি ব্যবহার করতে পারবেন না? (আমি যখন জিজ্ঞাসা করেছি তখন উত্তরটি আমি জানতাম)।
EDIT2
avr জন্য
avr-gcc --version
avr-gcc (GCC) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
খারাপ অভ্যাস এড়াতে বা 8 বিটের তুলনা করা নয়
arm-none-eabi-gcc --version
arm-none-eabi-gcc (GCC) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
পরিষ্কারভাবে অপ্টিমাইজেশন চালু ছিল এটি আমার আউটপুটটির সাথে কীভাবে তুলনা করে তা দেখতে আপনার নিজের সংকলকটির সাথে চেষ্টা করতে কেবল এক সেকেন্ড সময় নেয়, তবে যাইহোক:
whatever-gcc -O2 -c so.c -o so.o
whatever-objdump -D so.o
এবং হ্যাঁ বাইট সাইজের ভেরিয়েবলের জন্য বাইটস ব্যবহার করা অবশ্যই কোনও এভিআর, পিক ইত্যাদিতে আপনার স্মৃতি রক্ষা করবে এবং আপনি এটি সংরক্ষণের জন্য সত্যই চেষ্টা করতে চান ... আপনি যদি এটি ব্যবহার করছেন তবে এখানে যতটা সম্ভব দেখানো হয়েছে স্মৃতিতে যতটা সম্ভব নিবন্ধভুক্ত হতে চলেছে, তাই ফ্ল্যাশ সাশ্রয় অতিরিক্ত ভেরিয়েবল না রেখেই আসে, রাম সাশ্রয়টি আসল নাও হতে পারে ..