2012-06-24 105 views
68

x86-64 Tour of Intel Manuals से, मैंने पढ़ा32-बिट रजिस्टरों पर x86-64 निर्देश पूर्ण 64-बिट रजिस्टर के ऊपरी भाग को शून्य क्यों करते हैं?

शायद सबसे आश्चर्य की बात यह है कि एक अनुदेश जैसे MOV EAX, EBX स्वचालित रूप से RAX रजिस्टर के ऊपरी 32 बिट शून्य है।

इंटेल प्रलेखन एक ही स्रोत में उद्धृत (3.4.1.1 मैनुअल मूल वास्तुकला में 64-बिट मोड में सामान्य-प्रयोजन रजिस्टरों) हमें बताता है:

  • 64-बिट ऑपरेंड उत्पन्न एक 64 गंतव्य सामान्य उद्देश्य के लिए गंतव्य परिणाम।
  • 32-बिट ऑपरेंड 32-बिट परिणाम उत्पन्न करते हैं, गंतव्य सामान्य उद्देश्य के रजिस्टर में 64-बिट परिणाम के लिए शून्य-विस्तारित।
  • 8-बिट और 16-बिट ऑपरेंड 8-बिट या 16-बिट परिणाम उत्पन्न करते हैं। गंतव्य सामान्य प्रयोजन रजिस्टर के ऊपरी 56 बिट्स या 48 बिट्स (क्रमशः) को ऑपरेशन द्वारा संशोधित नहीं किया जाता है। यदि 8-बिट या 16-बिट ऑपरेशन का परिणाम 64-बिट पता गणना के लिए है, तो रजिस्टर को 64-बिट्स पर स्पष्ट रूप से साइन-इन करें। इस तरह के

    mov ax, bx 
    

    रूप

x86-32 और x86-64 विधानसभा में, 16 बिट निर्देश "अजीब" व्यवहार है कि eax के ऊपरी शब्द ध्यान केंद्रित किया गया है इस तरह का नहीं दिखाते।

इस प्रकार: इस व्यवहार को पेश करने का कारण क्या है? पहली नज़र में यह अजीब लगता है (लेकिन कारण यह हो सकता है कि मैं x86-32 असेंबली के quirks के लिए उपयोग किया जाता है)।

+11

यदि आप "आंशिक रजिस्टर स्टॉल" के लिए Google हैं, तो आपको उन समस्याओं के बारे में बहुत कुछ जानकारी मिलेगी जो वे (लगभग निश्चित रूप से) से बचने की कोशिश कर रहे हैं। –

+3

http://stackoverflow.com/questions/25455447/x86-64-registers-rax-eax-ax-al-overwriting-full-register-contents –

+1

न केवल "सबसे अधिक"।AFAIK, * सभी * निर्देश 'r32' गंतव्य ऑपरेशन के साथ विलय करने के बजाए उच्च 32, शून्य 32। उदाहरण के लिए, कुछ एंबलर 'pmovmskb r64, xmm' को' pmovmskb r32, xmm' के साथ बदल देंगे, एक आरईएक्स को सहेजेंगे, क्योंकि 64 बिट गंतव्य संस्करण समान रूप से व्यवहार करता है। भले ही [मैनुअल के ऑपरेशन सेक्शन] (http://www.felixcloutier.com/x86/PMOVMSKB.html) 32/64 बिट dest और 64/128/256b स्रोत के सभी 6 संयोजनों को सूचीबद्ध करता है, निहित शून्य-विस्तार आर 32 फॉर्म के आर 64 फॉर्म के स्पष्ट शून्य-विस्तार को डुप्लिकेट करता है। मैं एचडब्ल्यू कार्यान्वयन के बारे में उत्सुक हूं ... –

उत्तर

55

मैं एएमडी नहीं हूं या उनके लिए बोल रहा हूं, लेकिन मैं इसे वैसे ही करता। क्योंकि उच्च आधा शून्य करने से पिछले मान पर निर्भरता नहीं बनती है, कि सीपीयू को इंतजार करना होगा। रजिस्टर नामकरण तंत्र अनिवार्य रूप से पराजित हो जाएगा यदि यह इस तरह से नहीं किया गया था। इस तरह आप हर समय निर्भरता को तोड़ने के बिना 64 बिट मोड में तेज़ 32 बिट कोड लिख सकते हैं। इस व्यवहार के बिना, 64 बिट मोड में प्रत्येक 32 बिट निर्देश को पहले जो कुछ हुआ था उस पर इंतजार करना होगा, भले ही उस उच्च भाग का लगभग कभी उपयोग नहीं किया जाएगा।

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

+7

मुझे नहीं लगता कि यह अजीब बात है, मुझे लगता है कि वे बहुत ज्यादा तोड़ना नहीं चाहते थे और पुराने व्यवहार को वहां रखा था। –

+3

@Alex जब उन्होंने 32 बिट मोड पेश किया, तो उच्च भाग के लिए कोई पुराना व्यवहार नहीं था। इससे पहले कोई ऊंचा हिस्सा नहीं था .. इसके बाद इसके बाद इसे और नहीं बदला जा सका। – harold

+1

मैं 16-बिट ऑपरेंड के बारे में बात कर रहा था, उस मामले में शीर्ष बिट्स शून्य क्यों नहीं हो पा रहे हैं। वे गैर-64-बिट मोड में नहीं हैं। और यह 64-बिट मोड में भी रखा गया है। –

6

यह केवल निर्देशों में निर्देश और निर्देश सेट को बचाता है। मौजूदा (32-बिट) निर्देशों का उपयोग कर आप छोटे-छोटे मूल्यों को 64-बिट रजिस्टर में स्थानांतरित कर सकते हैं।

यह आपको MOV RAX, 42 के लिए 8 बाइट मानों को एन्कोड करने से बचाता है, जब MOV EAX, 42 का पुन: उपयोग किया जा सकता है।

यह अनुकूलन 8 और 16 बिट ऑप्स के लिए महत्वपूर्ण नहीं है (क्योंकि वे छोटे हैं), और नियमों को बदलने से पुराना कोड भी टूट जाएगा।

+4

यदि यह सही है, तो क्या यह 0 विस्तार के बजाय साइन-विस्तार करने के लिए अधिक समझ नहीं पाएगा? –

+0

@Damien_The_Unbeliever संभवतः। लेकिन शून्य-विस्तार बेहद सस्ता है। –

+2

@Alex: और साइन-एक्सटेंशन नहीं है? दोनों हार्डवेयर में बहुत सस्ते में किया जा सकता है। – jalf

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^