Intel x86 Assembly Language & Microarchitecture
अनुकूलन
खोज…
परिचय
टिप्पणियों
जब संदेह होता है, तो आप हमेशा बहुत व्यापक इंटेल 64 और आईए -32 आर्किटेक्चर ऑप्टिमाइज़ेशन रेफरेंस मैनुअल का उल्लेख कर सकते हैं, जो कि x86 आर्किटेक्चर के पीछे कंपनी का एक शानदार संसाधन है।
एक रजिस्टर को शून्य करना
किसी रजिस्टर को शून्य करने का स्पष्ट तरीका 0 से एक उदाहरण में MOV के लिए है:
B8 00 00 00 00 MOV eax, 0
ध्यान दें कि यह एक 5-बाइट अनुदेश है।
यदि आप झंडे लहराने के लिए तैयार हैं ( MOV झंडे को कभी भी प्रभावित नहीं करता है), तो आप XOR इंस्ट्रक्शन को अपने साथ रजिस्टर करने के लिए बिटवायर्न-एक्सओआर का उपयोग कर सकते हैं:
33 C0 XOR eax, eax
इस निर्देश के लिए केवल 2 बाइट्स की आवश्यकता होती है और सभी प्रोसेसरों पर तेजी से निष्पादित होता है ।
एक रजिस्टर में कैरी फ्लैग ले जाना
पृष्ठभूमि
यदि कैरी ( C ) ध्वज में एक मान है जिसे आप एक रजिस्टर में रखना चाहते हैं, तो भोला तरीका कुछ ऐसा करना है:
mov al, 1
jc NotZero
mov al, 0
NotZero:
'Sbb' का उपयोग करें
एक और अधिक सीधा रास्ता, कूद से बचने के लिए, "उधार के साथ घटाव" का उपयोग करना है:
sbb al,al ; Move Carry to al
यदि C शून्य है, तो al शून्य होगा। अन्यथा यह 0xFF ( -1 ) होगा। यदि आपको इसकी आवश्यकता 0x01 , तो जोड़ें:
and al, 0x01 ; Mask down to 1 or 0
पेशेवरों
- उसी आकार के बारे में
- दो या एक कम निर्देश
- कोई महंगी छलांग नहीं
विपक्ष
- यह तकनीक से अपरिचित पाठक के लिए अपारदर्शी है
- यह अन्य झंडे को बदल देता है
0 के लिए एक रजिस्टर का परीक्षण करें
पृष्ठभूमि
यह पता लगाने के लिए कि क्या कोई रजिस्टर शून्य रखता है, भोले तकनीक को ऐसा करना है:
cmp eax, 0
लेकिन अगर आप इसके लिए opcode को देखते हैं, तो आपको यह मिलता है:
83 F8 00 cmp eax, 0
test उपयोग करें
test eax, eax ; Equal to zero?
आपके द्वारा प्राप्त किए गए opcode की जाँच करें:
85 c0 test eax, eax
पेशेवरों
- केवल दो बाइट्स!
विपक्ष
- एक पाठक के लिए अपारदर्शी तकनीक से अपरिचित है
आप इस तकनीक पर प्रश्नोत्तर प्रश्न पर भी गौर कर सकते हैं।
लिनक्स सिस्टम कम ब्लोट के साथ कॉल करता है
32-बिट लिनक्स में, सिस्टम कॉल आमतौर पर सिसेंटर इंस्ट्रक्शन का उपयोग करके किया जाता है (मैं आमतौर पर कहता हूं क्योंकि पुराने प्रोग्राम अब int 0x80 उपयोग करते हैं), लेकिन यह एक प्रोग्राम में काफी जगह ले सकता है और इसलिए ऐसे तरीके हैं जो एक हैं चीजों को छोटा और गति देने के लिए कोनों को काट सकते हैं।
यह आमतौर पर 32-बिट लिनक्स पर एक सिस्टम कॉल का लेआउट है:
mov eax, <System call number>
mov ebx, <Argument 1> ;If applicable
mov ecx, <Argument 2> ;If applicable
mov edx, <Argument 3> ;If applicable
push <label to jump to after the syscall>
push ecx
push edx
push ebp
mov ebp, esp
sysenter
यह बड़े पैमाने पर सही है! लेकिन इस झंझट से बचने के लिए हम कुछ तरकीबें अपना सकते हैं।
सबसे पहले 3 32-बिट रजिस्टरों के आकार के घटे हुए एस्प के मान को 12 बाइट्स के लिए ईबीपी सेट करना है। यह तब तक बहुत अच्छा है जब तक कि आप कचरे के साथ ईबीपी, ईएक्सएक्स और ईएक्सएक्स के साथ ठीक नहीं हो जाते हैं (जैसे कि जब आप वैसे भी उन रजिस्टरों में एक मूल्य को आगे बढ़ाएंगे), हम एलईए अनुदेश का उपयोग करके ऐसा कर सकते हैं ताकि हमें ज़रूरत न हो ईएसपी के मूल्य को ही प्रभावित करने के लिए।
mov eax, <System call number>
mov ebx, <Argument 1>
mov ecx, <Argument 2>
mov edx, <Argument 3>
push <label to jump to after the syscall>
lea ebp, [esp-12]
sysenter
हालांकि, हम नहीं कर रहे हैं, अगर सिस्टम कॉल sys_exit है तो हम स्टैक पर कुछ भी धक्का नहीं देने के साथ दूर हो सकते हैं!
mov eax, 1
xor ebx, ebx ;Set the exit status to 0
mov ebp, esp
sysenter
3 या 5 से गुणा करें
पृष्ठभूमि
एक रजिस्टर और एक स्थिरांक के उत्पाद को प्राप्त करने और इसे दूसरे रजिस्टर में संग्रहीत करने के लिए, भोले को ऐसा करना है:
imul ecx, 3 ; Set ecx to 5 times its previous value
imul edx, eax, 5 ; Store 5 times the contend of eax in edx
lea प्रयोग करें
गुणा महंगा ऑपरेशन है। शिफ्ट्स और ऐड के संयोजन का उपयोग करना तेज़ है। ३२ या ६४ बिट रजिस्टर जो ३ या ५ द्वारा esp या rsp नहीं है, के कंटेस्टेंट को मेल करने की विशेष स्थिति के लिए, आप अंतिम निर्देश का उपयोग कर सकते हैं। यह उत्पाद की जल्दी गणना करने के लिए पता गणना सर्किट का उपयोग करता है।
lea ecx, [2*ecx+ecx] ; Load 2*ecx+ecx = 3*ecx into ecx
lea edx, [4*edx+edx] ; Load 4*edx+edx = 5*edx into edx
कई असेंबलर भी समझेंगे
lea ecx, [3*ecx]
lea edx, [5*edx]
सभी संभव गुणकों के लिए उन्हें अन्य ebp या rbp , जिसके परिणामस्वरूप निर्देश imul का उपयोग करने के imul ।
पेशेवरों
- बहुत तेजी से निष्पादित करता है
विपक्ष
- यदि आपका मल्टीप्लैंड
ebpयाrbpयहimulका उपयोग करके उन्हें एक बाइट लेता है - टाइप करने के लिए अधिक अगर आपके कोडांतरक शॉर्टकट का समर्थन नहीं करते हैं
- एक पाठक के लिए अपारदर्शी तकनीक से अपरिचित है