2014-05-16 3 views
8

or eax,eax और test eax,eax के बीच क्या अंतर है? मैंने देखा है विभिन्न compilers एक ही तुलना के लिए दोनों का उत्पादन और प्रलेखन वे बिल्कुल वही बात करते हैं, तो मैं सोच रहा हूँ क्यों वे नहीं है सब test eax,eax का उपयोग हो जाता है जहाँ तक। यह and eax,eax के बारे में सोच या तो के रूप में एक समान फैशन में झंडे स्थापित करेगा लेकिन मैं इसे या तो FreePascal, डेल्फी, या MSVC++ में नहीं देखा है।अंतर

मैंने डेल्फी में कुछ एएसएम ब्लॉक संकलित किए और असेंबलर स्रोत की जांच की और सभी 3 रूप ओपकों में सटीक समान लंबाई हैं और इंटेल प्रदर्शन पीडीएफ की भी जांच की है और यह कहता है कि उनके पास समान विलंबता और थ्रूपुट है।

संपादित करें:
सवाल विशिष्ट मामलों test eax,eax, or eax,eax और and eax,eax बीच अंतर के बारे में विशेष रूप है। सभी 3 रजिस्टरों, झंडे, ओपोड लंबाई, विलंबता, थ्रूपुट के लिए पूरी तरह से समान परिणाम देते हैं। और फिर भी अगर 0 परीक्षण, नहीं तो शून्य के लिए, या यदि हस्ताक्षर किए, कुछ compilers test eax,eax जबकि कुछ का उपयोग or eax,eax का उपयोग करेगा, और मैं सोच रहा था कि वे क्यों नहीं सब test eax,eax का उपयोग कर के बाद से यह बहुत थोड़ा साफ कोड बनाता है।

EDIT2:
संदर्भ मैं घर पर हूँ और केवल है और पुराने MSVC++ और डेल्फी यहाँ है, लेकिन शून्य अगर एक चर के परीक्षण के लिए, MSVC++ test eax,eax करता है, जबकि डेल्फी or eax,eax करता है।

+0

रजिस्टर नाम के आधार पर, मैंने अनुमान लगाया है [टैग: x86]। यदि यह गलत है, तो कृपया अपने प्रश्न को उचित प्रोसेसर आर्किटेक्चर के साथ दोबारा टैग करें। एक से अधिक है, और उनमें से प्रत्येक की अलग-अलग असेंबली भाषाएं हैं। –

+0

आप सही थे x86 के लिए, मेरा बुरा यह वहां नहीं डालने के लिए था। – Marladu

+0

लिंक किए गए डुप्लिकेट पर मेरा जवाब इस बारे में अधिक जानकारी देता है कि 'टेस्ट' बेहतर क्यों है, जिसमें कुछ कारणों का उल्लेख नहीं किया गया था। इन दिनों 'या एक ही,' पर विचार करने का एकमात्र कारण पी 6-पारिवारिक सीपीयू के लिए है, जहां एक रजिस्टर को फिर से लिखना इसे ऑर्डर-ऑफ-ऑर्डर कोर में "लाइव" रखता है, संभवतः बाद में निर्देशों के बाद रजिस्टर-स्टॉल स्टॉल से बच/घटाता है एक ही रजिस्टर पढ़ें। लेकिन टेस्ट/जेसीसी का मैक्रो-फ़्यूज़न आमतौर पर उस से अधिक होता है, जब तक कि प्रयोग एक विशिष्ट हॉटस्पॉट लाभ नहीं दिखाते। लेकिन शायद वह, और केवल जड़ता नहीं, यही कारण है कि डेल्फी 'या' का उपयोग करता है। –

उत्तर

6

सामान्य तौर पर, test और and के बीच फर्क सिर्फ इतना है कि test <reg>, <reg> अपने ऑपरेंड संशोधित नहीं करता है। अनिवार्य रूप से test परिणाम के गैर-झंडे भाग को छोड़कर and ऑपरेशन लागू करता है। यदि ऑपरेंड समान हैं, तो परिणाम समान होंगे (जैसा कि or होगा)।

test क्योंकि सूक्ष्म सेशन संलयन की तरह चीजों की एक बेहतर शिक्षा विकल्प हो सकता है। नतीजतन, test आमतौर पर तब तक पसंद किया जाता है जब तक कि गणना को दोहराया जाना न पड़े। एक ही चीज़ cmp/sub के लिए जाती है।

खोजें "विलय" के लिए इंटेल के दस्तावेज़ और आपको जानकारी मिल चाहिए।

+1

मैं एक प्रश्न में मुख्य प्रश्न में अधिक टेक्स्ट डालूंगा, लेकिन सवाल विशिष्ट मामले "परीक्षण ईएक्स, ईएक्स" "या ईएक्स, ईएक्स" "और ईएक्स, ईएक्स" के लिए था, जो रजिस्टरों के लिए पूरी तरह से समान परिणाम देते हैं, झंडे और ओपोड लंबाई। – Marladu

+1

'या eax, eax' या तो 'eax' को संशोधित नहीं करता है। –

+0

ओह मैं _see_, आप विशिष्ट मामले के बारे में बात कर रहे हैं जब ऑपरेंड समान हैं। क्षमा करें, मुझे उस पर उठाया जाना चाहिए था। मैं थोड़ा सा संपादित करूंगा। – gsg

2

बस थोड़ी सी दोहराने के लिए, और थोड़ी सी जोड़ने के लिए, @gsg संकेत दिया गया है, टेस्ट निर्देश थोड़ा सा तार्किक तुलना करता है (अनिवार्य रूप से उन्हें आंतरिक रूप से बिटिंग आंतरिक रूप से लेकिन परिणाम को संग्रहित नहीं करता) दो ऑपरेंड के और प्रोसेसर झंडे सेट करता है उस ऑपरेशन के परिणाम के अनुसार। या निर्देश एक लॉजिकल या गंतव्य के साथ स्रोत का है, परिणाम में गंतव्य संग्रहित करता है और परिणाम के अनुसार प्रोसेसर झंडे सेट करता है। वे दोनों प्रोसेसर झंडे को उसी तरह प्रभावित करते हैं। तो जब ऑपरेंड समान होते हैं, तो व्यवहार समान होता है। झंडे में कोई फर्क नहीं पड़ता। हालांकि, जब ऑपरेंड अलग होते हैं, तो उनका व्यवहार तब काफी अलग होता है। आप and eax,eax के साथ शून्य के लिए भी परीक्षण कर सकते हैं जो समान रूप से झंडे को भी प्रभावित करता है।

+0

क्या आप ईएक्स के मूल्य के बारे में सोच सकते हैं जहां विशिष्ट निर्देश "परीक्षण ईएक्स, ईएक्स" "या ईएक्स, ईएक्स" "और ईएक्स, ईएक्स" एक अलग परिणामस्वरूप रजिस्टर या झंडे देगा? ऑपरेशन के परिणाम के अनुसार – Marladu

+0

@ मार्लुडू 'या',' और', और 'टेस्ट' झंडे को प्रभावित करते हैं * समान रूप से * (मैंने अपना जवाब सही किया)। तो जब ऑपरेंड समान होते हैं (* उदा। *, 'या ईएक्स, ईएक्स',' टेस्ट ईएक्स, ईएक्स', 'और ईएक्स, ईएक्स') ध्वज के परिणाम समान होते हैं। यदि ऑपरेंड अलग हैं, तो 'test' और 'और' समान ध्वज परिणाम देंगे क्योंकि वे दोनों ऑपरेशन करते हैं, लेकिन' test' ऑपरेंड मानों को प्रभावित नहीं करेगा। या अलग-अलग ऑपरेंड मानों के आधार पर विभिन्न ध्वज परिणाम दे सकते हैं। – lurker

2

सर्किट निर्धारित करने के लिए कि test eax, eax के बाद eax की सामग्री के रूप में पहले अनुदेश सर्किट or eax, eax के लिए कि इस निष्कर्ष पर पहुंचने के लिए आवश्यक से अधिक आसान है एक ही हैं। इस कारण से, test बेहतर है।

कुछ compilers एक समय में or उत्पन्न हो सकता है जब यह कोई फर्क नहीं था (से पहले बाहर के आदेश निष्पादन), लेकिन यह (जबकि अभी तक अन्य OOO आजकल कुछ बाहर के आदेश प्रोसेसर के साथ सकारात्मक प्रभाव पड़ेगा प्रोसेसर इतने परिष्कृत होंगे कि वे or eax, eax को test eax, eax के बराबर के रूप में पहचानेंगे)।

मैं एक संदर्भ को न्यायोचित ठहरा है कि कुछ आधुनिक प्रोसेसर वास्तव में अनुमान लगाने के लिए कि or reg, regreg संशोधित नहीं करता है में सक्षम हैं नहीं मिल सकता है, लेकिन here is एक जवाब यह दावा करते हुए xchg reg, reg के लिए मामला है।

+0

'0x90' (' xchg eax, reg = eax के साथ reg' opcode) एक विशेष मामला है: इसे एक वास्तविक एनओपी के रूप में पहचाना जाता है, लेकिन 'xchg r, r के लिए opcode का उपयोग करके उसी निर्देश के 2-बाइट एन्कोडिंग/m32', एक एमओडीआरएम के साथ जो 'eax, eax' (या कोई अन्य समान, एन्कोड करता है) विशेष नहीं है। 32-बिट मोड '0x90' में' xchg eax, eax' भी है, लेकिन 64-बिट मोड 'xchg eax में, eax' शून्य में आरएक्स में ईएक्स बढ़ाएगा, और '0x90' ऐसा नहीं करता है: [एनओपी इसकी खुद की निर्देश संदर्भ पुस्तिका प्रविष्टि] (https://github.com/HJLebbink/asm-dude/wiki/NOP)। तो यदि आप x86-64 मोड में 'xchg eax, eax' को इकट्ठा करते हैं, तो इसे 2-बाइट एन्कोडिंग का उपयोग करना होगा। –