जीसीसी 4.4.3 ने निम्नलिखित x86_64 असेंबली उत्पन्न की। वह हिस्सा जो मुझे भ्रमित करता है वह mov %eax,%eax
है। रजिस्टर को अपने आप ले जाएं? क्यूं कर?जीसीसी ने mov% eax,% eax क्यों उत्पन्न किया और इसका क्या अर्थ है?
23b6c: 31 c9 xor %ecx,%ecx ; the 0 value for shift
23b6e: 80 7f 60 00 cmpb $0x0,0x60(%rdi) ; is it shifted?
23b72: 74 03 je 23b77
23b74: 8b 4f 64 mov 0x64(%rdi),%ecx ; is shifted so load shift value to ecx
23b77: 48 8b 57 38 mov 0x38(%rdi),%rdx ; map base
23b7b: 48 03 57 58 add 0x58(%rdi),%rdx ; plus offset to value
23b7f: 8b 02 mov (%rdx),%eax ; load map_used value to eax
23b81: 89 c0 mov %eax,%eax ; then what the heck is this? promotion from uint32 to 64-bit size_t?
23b83: 48 d3 e0 shl %cl,%rax ; shift rax/eax by cl/ecx
23b86: c3 retq
सी ++ इस कार्य के लिए कोड है:
uint32_t shift = used_is_shifted ? shift_ : 0;
le_uint32_t le_map_used = *used_p();
size_t map_used = le_map_used;
return map_used << shift;
एक le_uint32_t
एक वर्ग जो बड़े endian मशीनों पर बाइट-स्वैप संचालन लपेटता है। X86 पर यह कुछ भी नहीं करता है। used_p()
फ़ंक्शन मानचित्र बेस + ऑफसेट से पॉइंटर की गणना करता है और सही प्रकार का सूचक देता है।
देखें http://stackoverflow.com/questions/2703394/whats-the-point-of-lea-eax-eax – nos
@nos: संभवतः। लेकिन जीसीसी को किस कारण से एनओपी चाहिए? संरेखित करने के लिए कुछ भी नहीं है। –
भले ही कुछ संरेखित किया गया हो (यहां तक कि कहीं भी एक कूद हमें अगले निर्देश पर उतरने के लिए जरूरी नहीं दिखता), यह नहीं है - एसएचएल निर्देश का पता केवल बाइट को गठबंधन किया गया है। यह सिर्फ एक अनुकूलक बग की तरह दिखता है। विभिन्न झंडे और जीसीसी के हाल के संस्करणों का प्रयास करें (4.4.3 काफी पुराना हो रहा है) और देखें कि इसका क्या प्रभाव है। –