मैं लिनक्स कर्नेल में एक अप्रासंगिक मुद्दा डीबग कर रहा था और etcd प्रक्रिया को देखा, जिसे पर्यवेक्षक द्वारा प्रबंधित किया गया था, बार-बार पेज गलती अपवाद को मार रहा था और SIGSEGV प्राप्त कर रहा था।कंपाइलर द्वारा उत्पन्न असेंबली कोड में यह पैटर्न क्या है?
मैं उत्सुक हो गया और कार्यक्रम डिसअसेंबल करने objdump इस्तेमाल किया, और दोषयुक्त amd64 अनुदेश पाया जा करने के लिए:
89 04 25 00 00 00 00 mov %eax,0x0
मैं तो एक नमस्ते दुनिया कार्यक्रम के disassembly को देखा। मैंने कंपाइलर द्वारा उत्पन्न कोड में एक बहुत ही सामान्य पैटर्न देखा, जो कि एक समारोह के अंत में है, ret
के ठीक बाद, mov
पर jmp
फ़ंक्शन में वापस आ गया है। उदाहरण के लिए,
0000000000400c00 <main.main>:
400c00: 64 48 8b 0c 25 f0 ff mov %fs:0xfffffffffffffff0,%rcx
400c07: ff ff
...
400c4b: 48 83 7c 24 48 00 cmpq $0x0,0x48(%rsp)
400c51: 74 59 je 400cac <main.main+0xac>
400c53: 48 c7 04 24 c0 fc 47 movq $0x47fcc0,(%rsp)
400c5a: 00
...
400cab: c3 retq
400cac: 89 04 25 00 00 00 00 mov %eax,0x0
400cb3: eb 9e jmp 400c53 <main.main+0x53>
क्या यह कुछ चाल चलकर खेला जाता है? यदि ऐसा है, तो यह कैसे काम करता है? मैं 0x400c51
पर अनुमान लगा रहा हूं कि यह 0x400cac
पर कूदता है, SIGSEGV
ट्रिगर करता है, जिसे संभाला जाता है और फिर अगला निर्देश 0x400c53
पर वापस चला जाता है।
'mov% eax, 0x0' किसी रजिस्टर को तुरंत स्थानांतरित नहीं करता है। यह एक रजिस्टर को 0 पर ले जाता है (जब तक कि किसी बिंदु पर कोई फिक्सअप नहीं किया गया था जो किसी और चीज़ के साथ 0 को प्रतिस्थापित करता है)। यदि आप 'eax' को तत्काल 0 (जो इकट्ठा नहीं करेंगे) में स्थानांतरित करने का प्रयास करना चाहते हैं तो आप 'mov% eax, $ 0' (एक डॉलर चिह्न के साथ) लिखेंगे। – Michael
@ माइकल, सुधार के लिए धन्यवाद। मुझे भ्रम हो गया। –
कोई कंपाइलर अनुकूलित मोड में mov द्वारा 0 पर एक रजिस्टर सेट करेगा। वे ['xor reg, reg'] का उपयोग करेंगे (http://stackoverflow.com/q/33666617/995714) –