आप इस कोशिश कर सकते हैं अपने आप को इस सवाल का जवाब देखने के लिए:
movl $0,%eax
xor %eax,%eax
तो एकत्रित न इकट्ठा:
as xor.s -o xor.o
objdump -D xor.o
और
0: b8 00 00 00 00 mov $0x0,%eax
5: 31 c0 xor %eax,%eax
एक 32 बिट रजिस्टर के लिए mov अनुदेश है मिल 2.5 गुना बड़ा, राम से लोड करने में अधिक समय लगता है और उस कैश स्पेस का उपभोग करता है। दिन में लोड लोड अकेले एक हत्यारा था, आज मेमोरी चक्र समय और कैश स्पेस का तर्क दिया जा सकता है कि यह ध्यान देने योग्य नहीं है, लेकिन यह है कि यदि आपका कंपाइलर और/या कोड अक्सर ऐसा करता है तो आप कैश की हानि देखेंगे अंतरिक्ष और अधिक उत्खनन, और अधिक, धीमी, सिस्टम मेमोरी चक्र।
आधुनिक CPUs में, बड़े कोड-आकार भी डिकोडर्स को धीमा कर सकते हैं, शायद उन्हें प्रति चक्र अधिकतम x86 निर्देशों को डीकोड करने से रोक सकते हैं। (उदाहरण के लिए कुछ CPUs के लिए 16 बी ब्लॉक में 4 निर्देशों तक।)
performance advantages to xor over mov in some x86 CPUs (especially Intel's) that have nothing to do with code-size भी हैं, इसलिए x86 असेंबली में xor-zeroing हमेशा पसंद किया जाता है।
प्रयोगों का एक और सेट:
void fun1 (unsigned int *a)
{
*a=0;
}
unsigned int fun2 (unsigned int *a, unsigned int *b)
{
return(*a^*b);
}
unsigned int fun3 (unsigned int a, unsigned int b)
{
return(a^b);
}
0000000000000000 <fun1>:
0: c7 07 00 00 00 00 movl $0x0,(%rdi)
6: c3 retq
7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
e: 00 00
0000000000000010 <fun2>:
10: 8b 06 mov (%rsi),%eax
12: 33 07 xor (%rdi),%eax
14: c3 retq
15: 66 66 2e 0f 1f 84 00 nopw %cs:0x0(%rax,%rax,1)
1c: 00 00 00 00
0000000000000020 <fun3>:
20: 89 f0 mov %esi,%eax
22: 31 f8 xor %edi,%eax
24: c3 retq
प्रमुखों क्या चर मैं, मैं अपने प्रश्न को जन्म दे सकता के रूप में XOR दिखाने का पथ नीचे।चूंकि आपने यह निर्दिष्ट नहीं किया है कि प्रोसेसर या आप किस संदर्भ का जिक्र कर रहे थे, यह पूरी तस्वीर को पेंट करना मुश्किल है। उदाहरण के लिए यदि आप सी कोड के बारे में बात कर रहे हैं, तो आपको समझना होगा कि कौन से कंपाइलर उस कोड पर करते हैं, और यह फ़ंक्शन में कोड पर भारी निर्भर करता है, अगर आपके xor के समय कंपाइलर के पास रजिस्टर में ऑपरेंड होता है और निर्भर करता है आपके कंपाइलर सेटिंग्स पर आपको एक्सोर ईएक्स, ईएक्स मिल सकता है। या संकलक इसे एक mov reg, 0 में बदलने के लिए चुन सकता है, या कुछ = 0 बदल सकता है; एक xor reg, reg के लिए।
कुछ और दृश्यों विचार करने के लिए:
यदि चर को पता रजिस्टर में पहले से ही है:
7: c7 07 00 00 00 00 movl $0x0,(%rdi)
d: 8b 07 mov (%rdi),%eax
f: 31 c0 xor %eax,%eax
11: 89 07 mov %eax,(%rdi)
संकलक mov शून्य के बजाय XOR का चयन करेंगे। यदि आपने इस सी कोड को आजमाया है तो आपको यह मिलेगा:
void funx (unsigned int *a)
{
*a=*a^*a;
}
कंपाइलर इसे शून्य स्थान के साथ बदल देता है। बाइट्स की समान संख्या प्राप्त की गई, लेकिन एक की बजाय दो स्मृति की आवश्यकता होती है, और एक रजिस्टर जला दिया जाता है। और एक के बजाय निष्पादित करने के लिए तीन निर्देश। तो शून्य शून्य काफी बेहतर है।
अब अगर यह बाइट आकार के और एक रजिस्टर में है:
13: b0 00 mov $0x0,%al
15: 30 c0 xor %al,%al
कोड आकार में कोई अंतर नहीं। (लेकिन वे अभी भी अलग-अलग निष्पादित करते हैं)।
अब अगर आप एक और प्रोसेसर के बारे में बात कर रहे थे, मान लीजिए कि एआरएम
0: e3a00000 mov r0, #0
4: e0200000 eor r0, r0, r0
8: e3a00000 mov r0, #0
c: e5810000 str r0, [r1]
10: e5910000 ldr r0, [r1]
14: e0200000 eor r0, r0, r0
18: e5810000 str r0, [r1]
आप XOR (अनन्य या, ईओआर) का उपयोग करके कुछ भी सहेजने न: एक अनुदेश एक अनुदेश दोनों लाए जाने और निष्पादन है । यदि आपके पास किसी रजिस्टर में चर का पता है तो किसी भी प्रोसेसर की तरह, रैम में कुछ एक्सपोर्ट करना। यदि आपको xor करने के लिए डेटा को किसी अन्य रजिस्टर में कॉपी करना है, तो आप अभी भी दो मेमोरी एक्सेस और तीन निर्देशों के साथ समाप्त हो गए हैं। यदि आपके पास प्रोसेसर है जो स्मृति के लिए स्मृति कर सकता है तो शून्य की चाल सस्ता है क्योंकि आपके पास केवल एक मेमोरी एक्सेस है और प्रोसेसर के आधार पर एक या दो निर्देश हैं।
असल में यह इससे भी बदतर है: eor r0, r0, r0
required to have an input dependency on r0
(आउट-ऑफ-ऑर्डर निष्पादन सीमित है), स्मृति-आदेश नियमों के कारण। एक्सोर-शून्यिंग हमेशा शून्य उत्पन्न करता है, लेकिन केवल x86 असेंबली में प्रदर्शन में मदद करता है।
तो लब्बोलुआब यह, निर्भर करता है अगर तुम रजिस्टरों कोडांतरक में एक x86 सिस्टम पर कहीं भी 8088 से वर्तमान तक बात कर रहे हैं XOR है अक्सर तेजी क्योंकि अनुदेश छोटा होता है, तेजी से हासिल करेगा अगर कम कैश ले जाता है आपके पास एक है, अन्य कोड, आदि के लिए अधिक कैश छोड़ देता है। इसी तरह गैर-x86 परिवर्तनीय निर्देश लंबाई प्रोसेसर जिन्हें निर्देश में एन्कोड किए जाने वाले शून्य की आवश्यकता होती है, को भी लंबे निर्देश की आवश्यकता होगी, लंबे समय तक लाने का समय, कैश होने पर अधिक कैश का उपभोग किया जाएगा , आदि। तो xor तेज है (आमतौर पर, यह कैसे एन्कोड करता है पर निर्भर करता है)। यदि आपके पास सशर्त झंडे हैं तो आप बहुत खराब हो जाते हैं और आप उस झुकाव/xor को शून्य ध्वज सेट करना चाहते हैं, तो आपको सही निर्देश जला देना पड़ सकता है (कुछ प्रोसेसर पर mov झंडे को नहीं बदलता है)। कुछ प्रोसेसर के पास एक विशेष शून्य रजिस्टर होता है, यह सामान्य उद्देश्य नहीं होता है, जब आप इसका उपयोग करते हैं तो आपको एक शून्य मिल जाता है जिससे आप अधिक सामान्य उपयोग के मामले को बिना किसी निर्देश स्थान को एन्कोड कर सकते हैं या एक अतिरिक्त निर्देश चक्र को एक शून्य में तुरंत शून्य लोड कर सकते हैं । उदाहरण के लिए msp430, 0x1234 के एक कदम के लिए आपको दो शब्द निर्देश होंगे, लेकिन 0x0000 या 0x0001 को ले जाएं और कुछ अन्य स्थिरांक को एक ही निर्देश शब्द में एन्कोड किया जा सकता है।यदि आप राम में एक चर के बारे में बात कर रहे हैं, तो सभी प्रोसेसर को मेमोरी में डबल हिट होगा, रीड-संशोधित-दो मेमोरी चक्र लिखने के लिए निर्देशों को गिनती नहीं है, और यदि पढ़ा जाता है तो कैश लाइन भरने का कारण बनता है (लिखना तब होगा बहुत तेज़), लेकिन पढ़े बिना लिखने के लिए केवल कैश द्वारा सही हो सकता है और बहुत तेज़ी से निष्पादित हो सकता है क्योंकि प्रोसेसर समानांतर में चल रहा था, जबकि प्रोसेसर चल रहा था (कभी-कभी आपको वह प्रदर्शन लाभ मिलता है, कभी-कभी नहीं, हमेशा ट्यून करते हैं इसके लिए)। X86 और संभावित पुराने प्रोसेसर कारण हैं कि आप शून्य को स्थानांतरित करने के बजाय xoring की आदत क्यों देखते हैं। प्रदर्शन लाभ अभी भी उन विशिष्ट अनुकूलन के लिए है, सिस्टम मेमोरी अभी भी बहुत धीमी है और कोई भी अतिरिक्त मेमोरी चक्र महंगा है, वैसे ही किसी भी कैश को फेंक दिया जाता है महंगा है। हाफवे सभ्य कंपाइलर्स, यहां तक कि जीसीसी, मैं एक xor i का पता लगाऊंगा, मैं i = 0 के समतुल्य होने के नाते और मामले के आधार पर बेहतर (औसत प्रणाली पर) निर्देश अनुक्रम के आधार पर चुनता हूं।
माइकल एब्राश द्वारा जेन ऑफ असेंबली की एक प्रति प्राप्त करें। अच्छी, उपयोग की गई प्रतियां एक उचित मूल्य ($ 50 से कम) पर उपलब्ध हैं, भले ही आप $ 80 प्रतियों के लिए जाएं, यह इसके लायक है। विशेष 8088 "साइकिल खाने वालों" से परे देखने की कोशिश करें और सामान्य विचार प्रक्रिया को समझें जो वह सिखाने की कोशिश कर रहा है। फिर आप अपने कोड को अलग-अलग कर सकते हैं, आदर्श रूप से कई अलग-अलग प्रोसेसर के लिए। जो आपने सीखा है उसे लागू करें ...
संभावित डुप्लिकेट [xor reg का उपयोग करते हुए, reg mov reg पर लाभ देते हैं, 0?] (Http://stackoverflow.com/questions/1135679/does-using-xor-reg-reg-give-advantage-over -mov-reg-0) –
['xor eax, eax' x86 asm में एक रजिस्टर को शून्य करने का सबसे अच्छा तरीका है (कई कारणों से, केवल कोड-आकार नहीं)] (http://stackoverflow.com/questions/33666617/सबसे अच्छा तरीका-से-सेट-ए-रजिस्टर-टू-शून्य-इन-x86-assembly-xor-mov-or-और), लेकिन सी स्रोत कोड में आपको हमेशा 'var = 0; 'और संकलक को आपके लिए xor का उपयोग करने दें। 'Var^= var' लिखें, क्योंकि इसका शून्य लाभ और कई संभावित नुकसान हैं (उदा। ऑप्टिमाइज़र को हरा देना, विशेष रूप से यदि var अनियमित है)। केवल एक टिप्पणी पोस्ट कर रहा है क्योंकि यह सवाल एएसएम बनाम कंपाइलर इनपुट के बारे में पूछने के बारे में उलझन में प्रतीत होता है। –