assembly - एलआईए निर्देश का उद्देश्य क्या है?




x86 x86-64 (10)

मेरे लिए, यह सिर्फ एक मजेदार एमओवी की तरह लगता है। इसका उद्देश्य क्या है और मुझे इसका उपयोग कब करना चाहिए?


8086 में निर्देशों का एक बड़ा परिवार है जो एक रजिस्टर ऑपरेंड और एक प्रभावी पता स्वीकार करता है, उस प्रभावी पते के ऑफसेट भाग की गणना करने के लिए कुछ गणना करता है, और रजिस्टर और स्मृति से जुड़े स्मृति में कुछ ऑपरेशन करता है। उस वास्तविक स्मृति ऑपरेशन को छोड़ने के अलावा उस परिवार में दिए गए निर्देशों में से एक को उपरोक्त व्यवहार करना बहुत आसान था। यह, निर्देश:

mov ax,[bx+si+5]
lea ax,[bx+si+5]

लगभग समान रूप से आंतरिक रूप से कार्यान्वित किया गया था। अंतर एक छोड़ दिया कदम है। दोनों निर्देश कुछ इस तरह काम करते हैं:

temp = fetched immediate operand (5)
temp += bx
temp += si
address_out = temp  (skipped for LEA)
trigger 16-bit read  (skipped for LEA)
temp = data_in  (skipped for LEA)
ax = temp

इंटेल ने क्यों सोचा कि यह निर्देश मूल्यवान था, मुझे बिल्कुल यकीन नहीं है, लेकिन तथ्य यह है कि इसे लागू करने के लिए सस्ता था एक बड़ा कारक होगा। एक और कारक यह तथ्य होगा कि इंटेल के असेंबलर ने बीपी रजिस्टर के सापेक्ष परिभाषित करने के लिए प्रतीकों को अनुमति दी थी। अगर fnord को बीपी-रिश्तेदार प्रतीक (जैसे बीपी +8) के रूप में परिभाषित किया गया था, तो कोई कह सकता है:

mov ax,fnord  ; Equivalent to "mov ax,[BP+8]"

यदि कोई बीपी-रिश्तेदार पते पर डेटा स्टोर करने के लिए स्टॉस की तरह कुछ उपयोग करना चाहता था, तो कहने में सक्षम होना

mov ax,0 ; Data to store
mov cx,16 ; Number of words
lea di,fnord
rep movs fnord  ; Address is ignored EXCEPT to note that it's an SS-relative word ptr

इससे अधिक सुविधाजनक था:

mov ax,0 ; Data to store
mov cx,16 ; Number of words
mov di,bp
add di,offset fnord (i.e. 8)
rep movs fnord  ; Address is ignored EXCEPT to note that it's an SS-relative word ptr

ध्यान दें कि दुनिया को "ऑफ़सेट" भूलना DI 8 में जोड़े जाने के लिए मूल्य 8 की बजाय स्थान [बीपी +8] की सामग्री का कारण बनता है। उफ़।


अब्रैश द्वारा "विधानसभा के जेन" से:

LEA , एकमात्र निर्देश जो मेमोरी एड्रेसिंग गणना करता है लेकिन वास्तव में स्मृति को संबोधित नहीं करता है। LEA एक मानक मेमोरी एड्रेसिंग एड्रेस को स्वीकार करता है, लेकिन निर्दिष्ट रजिस्टर में गणना की गई मेमोरी ऑफ़सेट स्टोर करने से ज्यादा कुछ नहीं करता है, जो कि कोई सामान्य उद्देश्य रजिस्टर हो सकता है।

यह हमें क्या देता है? दो चीजें जो ADD प्रदान नहीं करती है:

  1. दो या तीन ऑपरेंड के साथ अतिरिक्त प्रदर्शन करने की क्षमता, और
  2. किसी भी रजिस्टर में परिणाम स्टोर करने की क्षमता; स्रोत ऑपरेशंस में से केवल एक नहीं।

और LEA झंडे को नहीं बदलता है।

उदाहरण

  • LEA EAX, [ EAX + EBX + 1234567 ] EAX + EBX + 1234567 गणना करता है (यह तीन ऑपरेंड है)
  • LEA EAX, [ EBX + ECX ] परिणाम के साथ ओवरराइड किए बिना EBX + ECX गणना करता है।
  • निरंतर (दो, तीन, पांच या नौ) द्वारा गुणा, यदि आप इसे LEA EAX, [ EBX + N * EBX ] ईबीएक्स LEA EAX, [ EBX + N * EBX ] (एन 1,2,4,8) कर सकते हैं।

अन्य उपयोगकेस लूप में आसान है: LEA EAX, [ EAX + 1 ] और INC EAX बीच का अंतर यह है कि बाद में EFLAGS बदलता है लेकिन पूर्व नहीं करता है; यह CMP राज्य को संरक्षित करता है।


एलआईए: सिर्फ एक "अंकगणितीय" निर्देश ..

एमओवी ऑपरेंड के बीच डेटा स्थानांतरित करता है लेकिन ली केवल गणना कर रहा है


ऐसा इसलिए है क्योंकि इसके बजाय आप कोड लिखते हैं

mov dx,offset something

आप बस लिख सकते हैं

lea dx,something

जैसा कि मौजूदा उत्तरों का उल्लेख है, LEA पास मेमोरी एक्सेस किए बिना अंकगणित मेमोरी को निष्पादित करने के फायदे हैं, अंकगणितीय परिणाम को सरल निर्देश के बजाय एक अलग रजिस्टर में सहेजना है। असली अंतर्निहित प्रदर्शन लाभ यह है कि आधुनिक प्रोसेसर में एक अलग एलआईएल एएलयू इकाई और प्रभावी पता उत्पादन ( LEA और अन्य मेमोरी संदर्भ पता सहित) के लिए बंदरगाह है, इसका मतलब है कि एएलयू में अंकगणितीय संचालन और समानांतर में अन्य सामान्य अंकगणितीय ऑपरेशन किया जा सकता है एक कोर में

एलआईए इकाई के बारे में कुछ विवरणों के लिए हैसवेल आर्किटेक्चर के इस आलेख को देखें: http://www.realworldtech.com/haswell-cpu/4/

अन्य उत्तरों में उल्लिखित एक और महत्वपूर्ण बिंदु LEA REG, [MemoryAddress] निर्देश पीआईसी (स्थिति स्वतंत्र कोड) है जो इस निर्देश में पीसी एड्रेस एड्रेस को संदर्भित करने के लिए पीसी रिश्तेदार पते को MemoryAddress । यह MOV REG, MemoryAddress से अलग है जो रिश्तेदार आभासी पते को एन्कोड करता है और आधुनिक ऑपरेटिंग सिस्टम में स्थानांतरित करने / पैचिंग की आवश्यकता होती है (जैसे एएसएलआर सामान्य सुविधा है)। इसलिए LEA का उपयोग ऐसे गैर पीआईसी को पीआईसी में बदलने के लिए किया जा सकता है।


यहाँ एक उदाहरण है।

// compute parity of permutation from lexicographic index
int parity (int p)
{
  assert (p >= 0);
  int r = p, k = 1, d = 2;
  while (p >= k) {
    p /= d;
    d += (k << 2) + 6; // only one lea instruction
    k += 2;
    r ^= p;
  }
  return r & 1;
}

संकलक विकल्प के रूप में -ओ (ऑप्टिमाइज़) के साथ, जीसीसी को संकेत कोड लाइन के लिए ली निर्देश मिलेगा।


सभी स्पष्टीकरणों के बावजूद, एलआईए एक अंकगणितीय ऑपरेशन है:

LEA Rt, [Rs1+a*Rs2+b] =>  Rt = Rs1 + a*Rs2 + b

यह सिर्फ इतना है कि इसका नाम एक शिफ्ट + एड ऑपरेशन के लिए बेहद बेवकूफ है। इसका कारण शीर्ष रेटेड उत्तरों में पहले ही समझाया गया था (यानी इसे उच्च स्तरीय मेमोरी संदर्भों को सीधे मैप करने के लिए डिज़ाइन किया गया था)।


सीईओ द्वारा प्रभावी पतों की समय लेने वाली गणना से बचने के लिए एलआईए निर्देश का उपयोग किया जा सकता है। यदि किसी पते का बार-बार उपयोग किया जाता है तो इसे हर बार प्रभावी पते की गणना करने के बजाय इसे रजिस्टर में स्टोर करना अधिक प्रभावी होता है।


LEA पर MOV का उपयोग करने का सबसे बड़ा कारण यह है कि यदि आपको पता लगाने के लिए उपयोग करने वाले रजिस्टरों पर अंकगणित करने की आवश्यकता है। प्रभावी रूप से, आप संयोजन में कई रजिस्टरों पर प्रभावी रूप से "मुक्त" के लिए पॉइंटर अंकगणित की मात्रा का प्रदर्शन कर सकते हैं।

इसके बारे में वास्तव में भ्रमित करने वाला यह है कि आप आम तौर पर एक MOV तरह एक MOV लिखते हैं लेकिन आप वास्तव में स्मृति को अस्वीकार नहीं कर रहे हैं। दूसरे शब्दों में:

MOV EAX, [ESP+4]

इससे ESP+4 अंक EAX में की सामग्री को स्थानांतरित कर दिया जाएगा।

LEA EAX, [EBX*8]

इससे प्रभावी पता EBX * 8 को EAX में स्थानांतरित किया जाएगा, जो उस स्थान में नहीं मिलता है। जैसा कि आप देख सकते हैं, भी, दो (स्केलिंग) के कारकों से गुणा करना संभव है जबकि एक MOV जोड़ने / घटाने के लिए सीमित है।


lea "लोड प्रभावी पता" का संक्षेप है। यह स्रोत ऑपरेंड द्वारा गंतव्य ऑपरेंड में स्थान संदर्भ का पता लोड करता है। उदाहरण के लिए, आप इसका उपयोग कर सकते हैं:

lea ebx, [ebx+eax*8]

एक ही निर्देश के साथ ebx पॉइंटर eax आइटम (64-बिट / तत्व सरणी में) को स्थानांतरित करने के लिए। असल में, आप x86 आर्किटेक्चर द्वारा समर्थित जटिल एड्रेसिंग मोड से लाभप्रद रूप से पॉइंटर्स में हेरफेर करने के लिए लाभ उठाते हैं।





x86-16