2011-09-23 9 views
5

मैंने पढ़ा है कि अगर eflags बिट 18 (एसी-संरेखण जांच) संशोधित किया जा सकता है, तो आप जानते हैं कि सीपीयू 486 या नया है। 386 पर, बिट संशोधन का विरोध करता है।x86 eflags बिट 18 (संरेखण जांच) कैसे काम करता है? (386 बनाम 486 और बाद में जांचने के लिए संबंधित।)

मैं this site से निम्नलिखित विधानसभा कोड को उठा लिया और कहा कि संपूर्ण टिप्पणियां (अजीब वाक्य रचना बरकरार छोड़कर) है:

asm 
    mov bx,sx   ; Save the stack pointer to bx (is sx a typo or a real register?). 
    and sp,$fffc   ; Truncate the stack pointer to a 4-byte boundary. 
    pushfl    ; Push the eflags register to the stack. 
    pop eax    ; Pop it into eax. 
    mov ecx,eax   ; Save the original eflags value into ecx. 
    xor eax,$40000  ; Flip bit 18 in eax. 
    push eax    ; Push eax to the stack. 
    popfl     ; Pop modified value into eflags. 
    pushfl    ; Push eflags back onto the stack. 
    pop eax    ; Pop it into eax. 
    xor eax,ecx   ; Get changed bits from the original value. 
    setz al    ; Set al register to 1 if no bits changed (0 otherwise). 
    and sp,$fffc   ; Truncate the stack pointer to a 4-byte boundary. 
    push ecx    ; Push ecx (original eflags) to stack. 
    popfl     ; Pop it into eflags to restore the original value. 
    mov sp,bx   ; Restore the original stack pointer. 
end ['eax','ebx','ecx']; 

सीपीयू एक 386 अगर अल रजिस्टर अंत में 1 पर सेट है है (शुरुआत से यह मानते हुए कि यह पुराना नहीं है), और यह 486 या अन्यथा अन्यथा है। मैं इस भाग को समझता हूँ।

जो मुझे समझ में नहीं आता है, फ्लैग संशोधन परीक्षण करने से पहले स्टैक पॉइंटर को 4-बाइट सीमा में क्यों छोटा किया जाना चाहिए? मुझे लगता है कि यह बिट 18 सेट करने के लिए है, क्योंकि यह सब के बाद संरेखण बिट है ... लेकिन 0x40000 वाला xor इसके मूल्य के बावजूद थोड़ा सा फ्लिप करेगा। दूसरे शब्दों में, संशोधन परीक्षण के प्रारंभिक मूल्य के बावजूद एक ही परिणाम होना चाहिए, है ना?

यदि उत्तर नहीं है, तो मेरा सबसे अच्छा [अशिक्षित] अनुमान "क्यों" है, "शायद निम्नलिखित पुश/पॉप निर्देश संरेखण को मजबूर कर सकते हैं? यह पहले असाइन किए गए स्टैक पॉइंटर को संरेखित करेगा और संरेखण बिट को फ़्लिप करने का कारण बन जाएगा 0 से 1 तक ही। उस स्थिति में, एक सफल संशोधन असफल दिखाई देगा, और इसके विपरीत। " (संपादित करें: यह निश्चित रूप से गलत है, क्योंकि संरेखण बिट संरेखण को ट्रैक करने के बजाए लागू करने के बारे में है। इसके अलावा, मुझे संदेह है कि पॉप/पुश किसी भी पहले असाइन किए गए स्टैक पर संरेखण को मजबूर करेगा।)

भले ही ऐसा मामला हो, परीक्षण के बाद फिर से स्टैक पॉइंटर को संरेखित करने का उद्देश्य क्या है (मूल eflags और स्टैक पॉइंटर को बहाल करने से ठीक पहले)? क्या यह पहले से ही 4-बाइट सीमा पर नहीं होना चाहिए? यदि नहीं, तो 4-बाइट मानों को धक्का/पॉप करने से यह कैसे बदल सकता है?

संक्षेप में, कुछ निर्देश मेरे लिए अनावश्यक लगते हैं, और मुझे लगता है कि मुझे कुछ महत्वपूर्ण याद आना चाहिए। क्या यहां कोई इसे समझा सकता है?

(साइड प्रश्न: पहली पंक्ति "एसएक्स" से मूल्य को बीएक्स में कॉपी करती है। मैंने कभी भी एसएक्स रजिस्टर का संदर्भ कभी नहीं देखा है। क्या यह वास्तव में मौजूद है, या यह एक टाइपो है? 'एक्स' कुंजी कम से कम 'पी' कुंजी से बहुत कम है, कम से कम यूएस कीबोर्ड पर।)

संपादित करें: अब इस प्रश्न का उत्तर दिया गया है, मैंने कोड में दो संरेखण लाइनों से गलत टिप्पणी निकालने का निर्णय लिया है। मैंने मूल रूप से एक धारणा की है कि ढेर को संरेखित करना संरेखण बिट सेट करेगा, और मैंने लिखा है कि मेरी टिप्पणी में (शेष प्रश्न इस गलत तर्क के साथ जारी है)। इसके बजाए, संरेखण चेक बिट वास्तव में संरेखण को लागू करने के बजाय संरेखण को लागू करने के बारे में है (क्योंकि इसे ट्रैक करने के बजाए), जैसा कि सिगबस के बारे में फ्लोलो का उत्तर इंगित करता है। मैंने समान प्रश्न वाले लोगों को भ्रमित करने से बचने के लिए टिप्पणियों को ठीक करने का निर्णय लिया।

+0

386 को खोजने के लिए आपने किस संग्रहालय को तोड़ दिया? आप बेहतर इसे वापस रखेंगे। –

+0

एलओएल! मैंने अपने ज्ञान के लिए 386 डेस्कटॉप कभी नहीं छुआ है ... मैंने दिन में पुराने 286 के साथ गड़बड़ी की, लेकिन मैंने उस से सीधे पेंटियम 75 तक छोड़ा। मैंने सीपीयूआईडी निर्देश को कॉल करने से पहले अपने अड्डों को कवर करने का फैसला किया (सबसे पहले सुनिश्चित करें कि आपके पास 386 नहीं है, फिर CPUID की उपस्थिति के लिए eflags बिट 21 का परीक्षण करें), ऑफ-मौके में कुछ पागल ने कभी भी प्राचीन हार्डवेयर पर अपने कोड का उपयोग करने का निर्णय लिया। मुझे लगता है कि मैं सिर्फ गुदा हूं ... लेकिन कम से कम मैं 8-बिट और 16-बिट CPU की जांच नहीं कर रहा हूं, क्योंकि आधुनिक कंपाइलर्स स्पष्ट रूप से उन लोगों के लिए कोड भी उत्पन्न नहीं करते हैं। ;) –

उत्तर

4

मेरा अनुमान बहुत आसान है: कोड सिगबस नहीं करना चाहता। यदि चेक संरेखण सेट नहीं है, और आप इसे सेट करते हैं, तो आप वास्तव में संरेखण जांच सक्षम करते हैं (जब यह कार्य करता है)। और जब स्टैक पॉइंटर को 4-बाइट सीमा से गठबंधन नहीं किया जाता है तो क्या होता है? आपको एक असाइन किए गए मेमोरी एक्सेस मिलती है, जिसके परिणामस्वरूप सिगबस होता है। और यदि आप उस अमान्य स्मृति पहुंच को नहीं देना चाहते हैं (जैसा कि आप परीक्षण उद्देश्य के लिए थोड़ा बदलना चाहते हैं), तो आपको यह ध्यान रखना होगा कि परीक्षण करते समय सभी एक्सेस सबसे खराब स्थिति मानते हैं (जो है: आपने इसे सक्षम किया है , और आपका ढेर गठबंधन करने से पहले था, क्योंकि इसकी आवश्यकता नहीं है, क्योंकि अब तक चेक अक्षम कर दिए गए थे)।

+0

धन्यवाद। यह पूरी तरह से पहले संरेखण निर्देश बताता है; मुझे थोड़ा सेट सेट (सिगबस की संभावना) के महत्व को नहीं पहचाना गया। क्या आपको पता है कि संरेखण फिर से क्यों सेट किया गया है, जब ऐसा लगता है कि स्मृति पहले ही गठबंधन होनी चाहिए? –

+1

+1 यही कारण है (ऐसा लगता है कि यह एक पास्कल खंड से है और इस प्रकार 16-बिट स्टैक से बाहर चला जाएगा, जिसे 32-बिट संरेखित होने की गारंटी नहीं है)। एसपी का दूसरा संरेखण वास्तव में अनावश्यक दिखता है, शायद यह सिर्फ इतना है कि संरेखण जांच को पॉपफ्लो निर्देश द्वारा संभावित रूप से सक्षम किया जा सकता है। – user786653

+0

फिर से धन्यवाद, दोस्तों! जब तक कि कोई और साथ न आए और बताए कि दूसरा संरेखण वास्तव में क्यों आवश्यक है, मैं इसे स्वीकार कर लेता हूं और मानता हूं कि दूसरा संरेखण अनावश्यक है। –

2

कोई एसएक्स रजिस्टर नहीं है। या तो एक टाइपो या एक स्मृति स्थान को संदर्भित करता है।

+0

धन्यवाद। मैं उस पर बैंकिंग कर रहा था जब मैंने पहली पंक्ति में स्टैक पॉइंटर को बचाने के बारे में टिप्पणी लिखी, लेकिन यह पुष्टि करना अच्छा है कि यह कुछ अस्पष्ट उप-रजिस्टर नहीं है। (मुझे लगता है कि वैसे भी समझ में नहीं आता है: 16-बिट एसपी 16-बिट बीएक्स से बहाल किया जाता है, इसलिए मूल बिट को पहले स्थान पर सहेजने के लिए 16 बिट से कम कुछ भी नहीं होगा।) –