दिलचस्प पोस्ट
एंड्रॉइड में स्पिनर पर छोटे त्रिकोण का रंग बदलें प्रतिनिधियों के फायदे क्या हैं? vb.net में एक विधि नाम के बाद डॉलर के चिह्न का क्या अर्थ है? Json.Net का उपयोग करते हुए JSON सरणी को पार्स करना अस्थायी बिंदु अंकगणित सटीक नतीजे का उत्पादन नहीं करते UILabel पाठ मार्जिन पीएल / पीजीएसक्यूएल के साथ पोस्टग्रेएसक्यूएल में एक रिकॉर्ड के रूप में कई फ़ील्ड लौटें सिस्टम क्या करता है। डबल मतलब "समान दृश्य नियंत्रक उदाहरण को एक बार से अधिक समर्थित नहीं है" अपवाद क्या 'ओवरराइड' कीवर्ड सिर्फ ओवरराइड वर्चुअल पद्धति के लिए एक चेक है? SQL में नया एक्सएमएल नोड एंट्री अपडेट करने या बनाने के लिए IF / ELSE कथन का उपयोग कैसे करें I "डिजाइन में सार बेस कक्षा का उपयोग न करें; लेकिन मॉडलिंग / विश्लेषण में " सूची बॉक्स पर हाइलाइटिंग को अक्षम कैसे करें, लेकिन चयन जारी रखें? पूर्ण पोस्टबैक के बिना AJAX updatepanel में फ़ाइल अपलोडिंग पर्ल 5 के फ़ंक्शन प्रोटोटाइप खराब क्यों हैं?

X86 विधानसभा में रजिस्टरों में इस्तेमाल किए जाने वाले पुश / पॉप निर्देशों का क्या कार्य है?

एडिबलर के बारे में पढ़ते समय मैं अक्सर लोगों के पास लिखता हूं कि वे प्रोसेसर के एक निश्चित रजिस्टर को पुश करते हैं और इसे बाद में इसे पिछले राज्य को बहाल करने के लिए पॉप करते हैं।

  • आप एक रजिस्टर कैसे कर सकते हैं? यह कहां पर धकेल दिया जाता है? यह क्यों आवश्यक है?
  • क्या यह एक एकल प्रोसेसर अनुदेश में उबाल हो जाता है या क्या यह अधिक जटिल है?

Solutions Collecting From Web of "X86 विधानसभा में रजिस्टरों में इस्तेमाल किए जाने वाले पुश / पॉप निर्देशों का क्या कार्य है?"

एक मूल्य (एक रजिस्टर में जरूरी नहीं भंडार) धक्का मतलब यह स्टैक में लिखने के लिए।

पॉपिंग का मतलब है कि एक रजिस्टर में स्टैक के शीर्ष पर जो कुछ भी बहाल हो रहा है ये बुनियादी निर्देश हैं:

 push 0xdeadbeef ; push a value to the stack pop eax ; eax is now 0xdeadbeef ; swap contents of registers push eax mov eax, ebx pop ebx 

यहां बताया गया है कि आप एक रजिस्टर कैसे दबाते हैं मुझे लगता है हम x86 के बारे में बात कर रहे हैं।

 push ebx push eax 

यह स्टैक पर धकेल दिया जाता है। ESP रजिस्टर का मान धक्का जाने वाले मान के आकार में घटा है क्योंकि स्टैक x86 प्रणालियों में नीचे की ओर बढ़ता है।

मूल्यों को संरक्षित करने की आवश्यकता है सामान्य उपयोग है

 push eax ; preserve the value of eax call some_method ; some method is called which will put return value in eax mov edx, eax ; move the return value to edx pop eax ; restore original eax 

एक push x86 में एक एकल निर्देश है, जो आंतरिक रूप से दो चीजें करता है

  1. ESP रजिस्टर के वर्तमान पते पर धकेल मूल्य को स्टोर करें।
  2. धक्का मूल्य के आकार के लिए ESP रजिस्टर को घटाएं।

यह कहां पर धकेल दिया जाता है?

esp - 4 ज्यादा ठीक:

  • esp को 4 से घटा दिया जाता है
  • मूल्य esp करने के लिए धक्का दिया है

pop इस उलट जाता है

सिस्टम वी एबीआई लिनक्स को एक rsp स्टैक स्थान पर rsp बिंदु बनाने के लिए कहता है, जब प्रोग्राम शुरू होता है: https://stackoverflow.com/a/32967009/895245 जो आपको आम तौर पर उपयोग करना चाहिए।

आप एक रजिस्टर कैसे कर सकते हैं?

न्यूनतम जीएनयू गैस उदाहरण:

 .data /* .long takes 4 bytes each. */ val1: /* Store bytes 0x 01 00 00 00 here. */ .long 1 val2: /* 0x 02 00 00 00 */ .long 2 .text /* Make esp point to the address of val2. * Unusual, but totally possible. */ mov $val2, %esp /* eax = 3 */ mov $3, %ea push %eax /* Outcome: - esp == val1 - val1 == 3 esp was changed to point to val1, and then val1 was modified. */ pop %ebx /* Outcome: - esp == &val2 - ebx == 3 Inverses push: ebx gets the value of val1 (first) and then esp is increased back to point to val2. */ 

उपरोक्त दावा के साथ

यह क्यों आवश्यक है?

यह सच है कि उन निर्देशों को आसानी से mov , add और sub द्वारा लागू किया जा सकता है

वे कारण मौजूद हैं, यह है कि उन निर्देशों के संयोजन इतने बार होते हैं, इंटेल ने उन्हें हमारे लिए प्रदान करने का निर्णय लिया।

कारण यह है कि उन संयोजनों के इतने बार होने पर, यह है कि वे अस्थायी रूप से मेमोरी में रजिस्टरों के मूल्यों को सहेजना और पुनर्स्थापित करना आसान बनाते हैं ताकि उन्हें ओवरराइट न मिले।

समस्या को समझने के लिए, हाथ से कुछ सी कोड संकलित करने का प्रयास करें।

एक बड़ी मुश्किल यह है, यह तय करना है कि प्रत्येक चर को कैसे संग्रहीत किया जाएगा।

आदर्श रूप से, सभी चर रजिस्टरों में फिट होंगे, जो कि एक्सेस करने के लिए सबसे तेज़ मेमोरी है (वर्तमान में रैम की तुलना में लगभग 100x तेज )

लेकिन ज़ाहिर है, हम आसानी से रजिस्टरों से अधिक चर, नेस्टेड फ़ंक्शंस की बहस के लिए विशेष रूप से कर सकते हैं, इसलिए केवल स्मृति को लिखना है

हम किसी भी मेमोरी पते पर लिख सकते हैं, लेकिन जब से फ़ंक्शन कॉल और रिटर्न के स्थानीय चर और तर्क ठीक स्टैक पैटर्न में फिट होते हैं, जो स्मृति विखंडन को रोकता है , यह उसके साथ निपटने का सबसे अच्छा तरीका है। एक ढेर आवंटन लिखने की पागलपन के साथ उस की तुलना करें

इसके बाद हम compilers हमारे लिए रजिस्टर आवंटन का अनुकूलन करते हैं, क्योंकि एनपी पूर्ण है, और एक कंपाइलर लिखने के सबसे कठिन भागों में से एक है। इस समस्या को रजिस्टर आवंटन कहा जाता है, और यह ग्राफ रंगांकन के लिए आइसोमोर्फिक है।

जब संकलक के आबंटक को सिर्फ रजिस्टरों के बदले मेमोरी में चीजें स्टोर करने के लिए मजबूर किया जाता है, जो कि फैल के रूप में जाना जाता है

क्या यह एक एकल प्रोसेसर अनुदेश में उबाल हो जाता है या क्या यह अधिक जटिल है?

हम सब यह सुनिश्चित करने के लिए जानते हैं कि इंटेल एक push और एक pop निर्देश लिखता है, इसलिए वे उस अर्थ में एक अनुदेश हैं।

आंतरिक रूप से, इसे कई माइक्रोकोडों तक विस्तारित किया जा सकता है, एक को esp से संशोधित करने के लिए और स्मृति IO करने के लिए और एक से अधिक चक्र लेना।

लेकिन यह भी संभव है कि एकल निर्देश अन्य निर्देशों के समतुल्य संयोजन की तुलना में तेज़ हो, क्योंकि यह अधिक विशिष्ट है

यह ज्यादातर संयुक्त राष्ट्र (डर) दस्तावेज है:

  • पीटर कॉर्ड्स का उल्लेख है कि http://agner.org/optimize/microarchitecture.pdf में वर्णित तकनीकों का सुझाव है कि push और pop एक एकल माइक्रो ऑपरेशन लेते हैं।
  • जोहान का उल्लेख है कि जब से पेंटियम एम इंटेल एक "स्टैक इंजन" का उपयोग करता है, जो प्रीकॉम्प्यूट किए गए esp + regsize और esp-regsize मानों को संग्रहीत करता है, एक एकल यूओपी में पुश करने और पॉप करने की अनुमति देता है। इसके बारे में भी बताया गया है: https://en.wikipedia.org/wiki/Stack_register
  • इंटेल माइक्रोकोड क्या है?
  • https://security.stackexchange.com/questions/29730/processor-microcode-manipulation-to-change-opcodes
  • प्रत्येक विधानसभा अनुदेश के लिए कितने CPU चक्र आवश्यक हैं?

लगभग सभी सीपीयू स्टैक का इस्तेमाल करते हैं। प्रोग्राम स्टैक हार्डवेयर समर्थित प्रबंधन के साथ LIFO तकनीक है।

स्टैक प्रोग्राम की मात्रा (रैम) स्मृति सामान्यतः CPU मेमोरी ढेर के शीर्ष पर आवंटित होता है और बढ़ता है (पुश निर्देश पर स्टैक पॉइंटर कम हो जाता है) विपरीत दिशा में। स्टैक में डालने के लिए एक मानक शब्द पुश है और स्टैक से निकालने के लिए POP है

स्टैक स्ट्रैक इरादा सीपीयू रजिस्टर के माध्यम से प्रबंधित किया जाता है, जिसे स्टैक पॉइंटर भी कहा जाता है, इसलिए जब सीपीयू प्रदर्शन करता है या पीओएसएच स्टैक पॉइंटर एक रजिस्टर या स्टैक्स मेमोरी में लगातार लोड / स्टोर करेगा और स्टेक पॉइंटर स्वत: कम हो जाएगा या (से) ढेर में popped

कोडांतरक निर्देशों के माध्यम से हम स्टोर करने के लिए स्टोर कर सकते हैं:

  1. सीपीयू रजिस्टरों और भी स्थिरांक
  2. कार्यों या प्रक्रियाओं के लिए पते लौटें
  3. फ़ंक्शंस / प्रक्रियाएं / आउट इन व्हेरिएबल्स
  4. कार्य / प्रक्रियाएं स्थानीय चर

धक्का देने और पॉपिंग रजिस्टरों इस तरह के दृश्यों के पीछे हैं:

 push reg <= same as => sub $8,%rsp # subtract 8 from rsp mov reg,(%rsp) # store, using rsp as the address pop reg <= same as=> mov (%rsp),reg # load, using rsp as the address add $8,%rsp # add 8 to the rsp 

ध्यान दें यह x86-64 एटीटीटीए वाक्यविन्यास है।

एक जोड़ी के रूप में उपयोग किया जाता है, यह आपको स्टैक पर एक रजिस्टर सहेजने और इसे बाद में पुनर्स्थापित करने देता है अन्य उपयोग भी हैं I