2010-01-25 12 views
25

मैं अपने कार्यक्रम के disassmbly के माध्यम से देख रहा था (क्योंकि यह दुर्घटनाग्रस्त हो गया), औरक्यों दृश्य स्टूडियो उपयोग xchg कुल्हाड़ी, कुल्हाड़ी

xchg ax, ax 

मैं इसे googled और पता चला यह अनिवार्य रूप से एक nop है के बहुत सारे देखा लेकिन दृश्य स्टूडियो एक नोप के बजाय xchg क्यों करता है?

आवेदन 2 स्मरक निर्देश एक ही द्विआधारी सेशन के लिए इकट्ठा एक सी # .NET3.5 64-बिट आवेदन, 86 पर दृश्य स्टूडियो

+1

इन निर्देशों का एक ही साथ जुड़े बाइट्स कर रहे हैं? एनओपी हेक्स 90 होना चाहिए। xchg कुल्हाड़ी है, एक 2 बाइट निर्देश कुल्हाड़ी? –

+0

यह मूल रूप से सोचा (या फिर भी याद किया गया) की तुलना में थोड़ा और अधिक ज्ञान के साथ एक प्रश्न बन गया। –

+0

अरे क्या आप मुझे बता सकते हैं कि आपके जैसे असेंबली कोड को कैसे देखें। मैं देखना चाहता हूं कि कैसे एक साधारण प्रोजेम को असेंबली में परिवर्तित किया जाता है। धन्यवाद – masfenix

उत्तर

33

द्वारा संकलित NOP अनुदेश XCHG AX, AX

है कोड। (असल में, मुझे लगता है कि एक असेंबलर अपने साथ किसी रजिस्टर के xchg का उपयोग कर सकता है, लेकिन AX या EAX आमतौर पर nop के लिए उपयोग किया जाता है जो मुझे पता है)।

xchg ax, ax में कोई पंजीकरण मूल्य बदलने और कोई झंडे बदलने की संपत्ति नहीं है (हे - यह कोई ऑप नहीं है!)।


संपादित (Anon द्वारा एक टिप्पणी के जवाब में।):

ओह सही - अब मुझे याद है xchg शिक्षा के लिए कई एनकोडिंग देखते हैं। कुछ बिट्स का एक mod ​​/ r/m सेट लेते हैं (जैसे कई इंटेल x86 आर्किटेक्चर निर्देश) जो एक स्रोत और गंतव्य निर्दिष्ट करते हैं। उन एन्कोडिंग में एक से अधिक बाइट लेते हैं। एक विशेष एन्कोडिंग भी है जो एक बाइट का उपयोग करती है और (E)AX के साथ एक सामान्य उद्देश्य रजिस्टर का आदान-प्रदान करती है। यदि निर्दिष्ट रजिस्टर (E)AX मुर्गी है तो आपके पास एकल-बाइट एनओपी निर्देश है। आप यह भी निर्दिष्ट कर सकते हैं कि (E)AXxchg निर्देश के बड़े संस्करण का उपयोग करके स्वयं के साथ आदान-प्रदान किया जा सकता है।

मेरा अनुमान है कि कि MSVC (E)AX स्रोत और गंतव्य जब यह कोई ऑपरेशन के लिए एक से अधिक बाइट ऊपर चबाना करना चाहता है के रूप में साथ xchg के कई बाइट संस्करण का उपयोग करता है - यह चक्र का एक ही नंबर एक बाइट xchg के रूप में लेता है , लेकिन अधिक जगह का उपयोग करता है। डिस्सेप्लर में आपको के रूप में डीकोड किए गए एकाधिक बाइट xchg दिखाई नहीं देंगे, भले ही परिणाम समान हो।

विशेष रूप xchg eax, eax या nop opcodes 0x90 या 0x87 0xc0 आप इसे 1 या 2 बाइट्स का उपयोग करना चाहते हैं पर निर्भर करता है के रूप में एन्कोड किया जा सकता है। विजुअल स्टूडियो डिस्सेबलर (और शायद अन्य) ओपोड 0x90 को NOP निर्देश के रूप में डीकोड करेगा और 0x87 0xc0 को xchg eax, eax के रूप में ऑपोडोड डीकोड करेगा।

यह थोड़ी देर के बाद से मैं विस्तृत विधानसभा भाषा काम किया है हो गया है इसलिए संभावना है कि मैं कम से कम एक गिनती यहाँ पर गलत हूँ रहे हैं ...

+0

फिर मैं एनओपी क्यों देखूं? – Malfist

+0

यह डिस्सेबलर स्मार्ट (या गूंगा, जो आप करना चाहते थे उसके आधार पर) होगा। क्या आप एक ही डिस्सेबलर का उपयोग करके दोनों डीकोड देखते हैं? यह देखने के लिए कुछ दिलचस्प हो सकता है। –

+0

यह दृश्य स्टूडियो डिस्सेबलर है ... – Malfist

8

xchg ax,ax और nop वास्तव में एक ही अनुदेश रहे हैं, वे करने के लिए नक्शे एक ही ऑपोड (0x90 iirc)। यह ठीक है, xchg ax,ax एक नो-ऑप है। किसी को कुछ भी नहीं करने वाले निर्देशों के साथ अतिरिक्त ऑपोडोड एन्कोडिंग क्यों बर्बाद करनी चाहिए?

संदिग्ध क्यों आप दोनों मनोनीत मुद्रित देखते हैं।मुझे लगता है कि यह आपके disassembly में सिर्फ एक दोष है, कोई बाइनरी अंतर नहीं है।

+1

0x90 9 0 ... .. – Earlz

+0

डू-कुछ निर्देशों पर ऑपोडोड एन्कोडिंग को बर्बाद करने का सवाल कुछ दिलचस्प मुद्दों को उठाता है, खासकर आर्किटेक्चर में जो अमान्य निर्देशों को फंसाने के लिए निर्दिष्ट हैं। एक तरफ, यदि ऑपोड स्पेस का एक महत्वपूर्ण हिस्सा कार्यात्मक रूप से समान निर्देशों द्वारा उपयोग किया जाता है, तो सभी के उपयोग को मना कर दिया जाता है, लेकिन इस तरह के एक एन्कोडिंग से दूसरों को भविष्य के संचालन के लिए उपलब्ध कराया जाएगा। दूसरी ओर, ऐसा करने से कुछ गतिशील-कोड-जनरेशन परिदृश्य अधिक कठिन हो सकते हैं, और यदि अमान्य ऑपकोड फंस जाएंगे, तो उन्हें अतिरिक्त ट्रैफ़िक की आवश्यकता होती है। – supercat

+0

@supercat: यह परिभाषित करने के लिए बस कुछ अलग है * अभी तक एक और * ओपोड जो कुछ भी नहीं करता है, है ना? – SamB

4

एमएसवीसी आम तौर पर डीबग बिल्ड के लिए संकलित कोड में एनओपी रखता है। यह & संपादित करना जारी रखने की अनुमति देता है।

5

दरअसल, xchg ax,ax यह है कि एमएस कैसे "66 9 0" को अलग करता है। 66 ऑपरेंड आकार ओवरराइड है, इसलिए यह पर eax के बजाय अनुमानित रूप से संचालित होता है। हालांकि, सीपीयू अभी भी इसे एक एनओपी के रूप में निष्पादित करता है। 66 उपसर्ग का उपयोग आकार में दो बाइट्स को बनाने के लिए किया जाता है, आमतौर पर संरेखण उद्देश्यों के लिए।

+0

विभिन्न आकारों के साथ कई अन्य एनओपी भी हैं और संकलक सर्वोत्तम फिट बैठता है http://stackoverflow.com/ एक/12564044/995714 –

2

मुझे नहीं पता कि इसमें सवाल के साथ कुछ करना है लेकिन कई विंडोज़ कार्य एमओवी ईडीआई, ईडीआई के साथ शुरू होते हैं। यह एक 2 बाइट एनओपी भी है। दो बाइट एनओपी हॉटपैच कोड के लिए उपयोगी हैं, क्योंकि आप सुरक्षित रूप से इसे एक छोटे जेएमपी के साथ बदल सकते हैं।

संदर्भ: http://blogs.msdn.com/b/oldnewthing/archive/2011/09/21/10214405.aspx

संबंधित मुद्दे