2010-03-01 13 views
24

इसलिए आज सुबह मैंने असेंबली के बारे में एक भ्रमित सवाल पोस्ट किया और मुझे कुछ महान वास्तविक मदद मिली, जिसे मैं वास्तव में सराहना करता हूं।असेंबली - .डेटा, .code, और रजिस्टर्स ...?

और अब मैं असेंबली में शामिल होना शुरू कर रहा हूं और यह समझने लगा हूं कि यह कैसे काम करता है।

जो चीजें मुझे लगता है मैं समझता हूं कि मैं ढेर, इंटरप्ट्स, बाइनरी/हेक्स, और सामान्य रूप से मूलभूत परिचालनों में से अधिकांश (jmp, push, mov, आदि) को समझता हूं।

  1. वास्तव में क्या .data खंड में हो रहा है: -

    अवधारणाओं कि मैं समझता हूँ के लिए संघर्ष कर रहा हूँ और नीचे हैं मदद करना चाहते हैं यदि आप निम्न में से किसी को संबोधित कर सकता है यह एक बड़ी मदद होगी ? क्या वे चर हैं जिन्हें हम घोषित कर रहे हैं?

  2. यदि हां, तो क्या हम बाद में कोड अनुभाग में चर घोषित कर सकते हैं? यदि नहीं, तो क्यों नहीं? यदि हां, तो हम कैसे और फिर डेटा अनुभाग का उपयोग क्यों करते हैं?
  3. एक रजिस्टर क्या है? यह एक चर से तुलना कैसे करता है? मेरा मतलब है कि मुझे पता है कि यह एक ऐसा स्थान है जो जानकारी का एक छोटा टुकड़ा संग्रहीत करता है ... लेकिन यह मेरे लिए एक चर की तरह लगता है।
  4. मैं एक सरणी कैसे बना सकता हूं? मुझे पता है कि यह यादृच्छिक लगता है, लेकिन मैं उत्सुक हूं कि मैं इस तरह कुछ करने के बारे में कैसे जाऊंगा।
  5. क्या प्रत्येक रजिस्टर के लिए सामान्य प्रथाओं की एक सूची है जिसके लिए प्रत्येक रजिस्टर का उपयोग किया जाना चाहिए? मैं अभी भी उन्हें पूरी तरह से नहीं प्राप्त करता हूं, लेकिन कुछ लोगों ने यह कहते हुए देखा है कि उदाहरण के लिए, एक निश्चित रजिस्टर का उपयोग प्रक्रियाओं से 'वापसी मूल्य' को स्टोर करने के लिए किया जाना चाहिए - क्या ऐसी प्रथाओं की व्यापक या कम से कम जानकारीपूर्ण सूची है?
  6. असेंबली सीखने के कारणों में से एक यह है कि मेरे उच्च स्तर कोड के पीछे क्या हो रहा है, यह बेहतर ढंग से समझना है। इसे ध्यान में रखते हुए - जब मैं सी ++ में प्रोग्रामिंग कर रहा हूं, तो मैं अक्सर ढेर और ढेर के बारे में सोच रहा हूं। असेंबली में मुझे पता है कि ढेर क्या है - 'ढेर' कहां है?

कुछ जानकारी: मैं WinAsm साथ masm32 उपयोग कर रहा हूँ एक IDE के रूप में है, और मैं मैं ऐसे C++/जावा के रूप में उच्च स्तर भाषाओं में पूर्व अनुभव प्रोग्रामिंग का एक बहुत कुछ है विंडोज 7 पर काम कर रहा हूँ।


संपादित करें: हर किसी की मदद के लिए धन्यवाद, सामान्य रूप से बेहद जानकारीपूर्ण! उत्तम सामग्री! हालांकि एक आखिरी बात - मैं सोच रहा हूं कि स्टैक पॉइंटर, और बेस पॉइंटर, या ईएसपी और ईबीपी के बीच क्या अंतर है। क्या कोई मेरी मदद कर सकता है?

संपादित करें: मुझे लगता है कि मुझे अब मिल गया है ... ईएसपी हमेशा ढेर के शीर्ष पर इंगित करता है। हालांकि, आप जो चाहें ईबीपी को इंगित कर सकते हैं। ईएसपी स्वचालित रूप से संभाला जाता है लेकिन आप जो भी चाहते हैं वह ईबीपी के साथ कर सकते हैं। उदाहरण के लिए:

push 6 
push 5 
push 4 
mov EBP, ESP 
push 3 
push 2 

इस परिदृश्य में, ईबीपी अब पता 4 पकड़े के लिए अंक, लेकिन ईएसपी अब पता पकड़े 2.

कोई वास्तविक आवेदन 6, 5 में के लिए अंक, और 4 हो सकता था फ़ंक्शन तर्क, जबकि 3 और 2 उस फ़ंक्शन के भीतर स्थानीय चर हो सकते हैं।

+0

क्या मैं पूछ सकता हूं कि क्या आपके पास कोई पुस्तक है, और यदि आप करते हैं, तो कौन सी पुस्तक हो सकती है? :) –

+0

नहीं, क्षमा करें! बस इंटरनेट। http://stackoverflow.com/questions/2352048/assembly-32-bit-vs-64-bit -> उस पोस्ट में मैंने उन संसाधनों की रूपरेखा दी है जिनका मैं उपयोग कर रहा हूं। मैंने आज विधानसभा सीखना शुरू कर दिया है, इसलिए मैं उस सूची पर काम करना जारी रखूंगा क्योंकि मैं अधिक संसाधन इकट्ठा करता हूं। – Cam

+0

मैं भी असेंबली सीखना शुरू कर रहा हूं। "पीडीएफ प्रोग्रामिंग" नामक मुफ्त पीडीएफ पुस्तक है जो काफी अच्छी लगती है। यह अभी मेरा मुख्य संसाधन है। – morgancodes

उत्तर

30

आइए आदेश देने का प्रयास करें!

  1. डेटा अनुभाग में कुछ भी शामिल है जिसे आप अपने प्रोग्राम के प्रवेश बिंदु को कॉल करने से पहले सिस्टम द्वारा स्वचालित रूप से प्रारंभ करना चाहते हैं। आप सही हैं, सामान्य रूप से वैश्विक चर यहां समाप्त होते हैं।शून्य-प्रारंभिक डेटा आम तौर पर निष्पादन योग्य फ़ाइल में शामिल नहीं होता है, क्योंकि इसका कोई कारण नहीं है - प्रोग्राम लोडर के कुछ निर्देश उस स्थान को उत्पन्न करने के लिए आवश्यक हैं। एक बार आपका प्रोग्राम चलने लगने के बाद, ज़ी और डेटा क्षेत्र आम तौर पर अदला-बदले होते हैं। Wikipedia में बहुत अधिक जानकारी है।

  2. वेरिएबल्स वास्तव में मौजूद नहीं हैं जब असेंबली प्रोग्रामिंग, कम से कम उस अर्थ में नहीं जब वे सी कोड लिख रहे हों। आपके पास यह निर्णय है कि आपने अपनी याददाश्त कैसे निकाली है इसके बारे में आपने किया है। वेरिएबल स्टैक पर हो सकते हैं, मेमोरी में कहीं, या सिर्फ रजिस्टरों में ही रह सकते हैं।

  3. रजिस्टर्स प्रोसेसर का आंतरिक डेटा संग्रहण हैं। आप सामान्य रूप से प्रोसेसर रजिस्टरों में मूल्यों पर संचालन कर सकते हैं। आप अपनी सामग्री को स्मृति से और लोड कर सकते हैं, जो कि आपका कंप्यूटर कैसे काम करता है इसका मूल संचालन है। यहां एक त्वरित उदाहरण है। इस सी कोड:

    int a = 5; 
    int b = 6; 
    int *d = (int *)0x12345678; // assume 0x12345678 is a valid memory pointer 
    *d = a + b; 
    

    की तर्ज पर कुछ (सरलीकृत) विधानसभा के लिए अनुवाद कर सकते हो:

    load r1, 5 
    load r2, 6 
    load r4, 0x1234568 
    add r3, r1, r2 
    store r4, r3 
    

    इस मामले में, आप चर के रूप में रजिस्टर के बारे में सोच सकते हैं, लेकिन सामान्य रूप में यह नहीं है आवश्यक है कि कोई एक चर हमेशा एक ही रजिस्टर में रहें; इस पर निर्भर करता है कि आपका दिनचर्या कितना जटिल है, यह संभव भी नहीं हो सकता है। आपको कुछ डेटा स्टैक पर धक्का देना होगा, अन्य डेटा बंद करना होगा, और इसी तरह। एक 'परिवर्तनीय' डेटा का तार्किक टुकड़ा है, जहां यह स्मृति या रजिस्टरों में नहीं रहता है, आदि

  4. एक सरणी केवल स्मृति का एक संगत ब्लॉक है - स्थानीय सरणी के लिए, आप केवल स्टैक पॉइंटर को उचित रूप से घटा सकते हैं । वैश्विक सरणी के लिए, आप डेटा अनुभाग में उस ब्लॉक को घोषित कर सकते हैं।

  5. रजिस्टरों के बारे में सम्मेलनों का एक समूह है - अपने प्लेटफ़ॉर्म के एबीआई को जांचें या सम्मेलन दस्तावेज़ को सही तरीके से उपयोग करने के बारे में विवरण के लिए कॉल करें। आपके असेंबलर दस्तावेज़ में जानकारी भी हो सकती है। ABI article on wikipedia देखें।

  6. आपका असेंबली प्रोग्राम एक ही सिस्टम को किसी भी सी प्रोग्राम को कॉल कर सकता है, ताकि आप हीप से स्मृति प्राप्त करने के लिए malloc() पर कॉल कर सकें।

+0

+1 फिर से धन्यवाद कार्ल। बहुत उपयोगी! विशेष रूप से 3 पर उदाहरण उपयोगी था। मुझे लगता है कि यह वास्तव में नीचे आता है, असेंबली सी से अलग होना चाहिए, अन्यथा यह वास्तव में सी होगा। # 4 के लिए ... मैंने सोचा था कि ढेर पहले बाहर सख्ती से पहले था। हालांकि मुझे लगता है कि आप बिना धक्का/पॉपिंग के ढेर से पढ़ सकते हैं? साथ ही, मुझे यह उपयोगी और प्रासंगिक लगता है: http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames – Cam

+2

हाँ आप पुश/पॉप के बिना स्टैक से पढ़ सकते हैं: आपको केवल स्टैक पॉइंटर और ऑफसेट की आवश्यकता है। X86 asm में स्टैक पॉइंटर एएसपी रजिस्टर में निहित है, इसलिए आप esp + ऑफ़सेट का उपयोग कर सकते हैं (वास्तव में, यदि आप एक सी ऐप को अलग करते हैं, तो आप इस विधि को फ़ंक्शन कॉल के भीतर 'स्थानीय' चरों तक पहुंचने के लिए उपयोग करेंगे)। – slugster

+1

@incrediman, स्टैक बस बाकी सब कुछ के साथ स्मृति में है, इसलिए आप इसे एक्सेस कर सकते हैं हालांकि आप चाहते हैं। फ़ंक्शन कॉल के लिए निष्पादन संदर्भ संग्रहीत करने के लिए इसका उपयोग करने के अर्थ में यह केवल एक ढेर है। –

14

मैं इसे जोड़ना चाहता हूं। कंप्यूटर पर प्रोग्राम आम तौर पर तीन खंडों में विभाजित होते हैं, हालांकि अन्य भी होते हैं।

कोड खंड - .code, .text: http://en.wikipedia.org/wiki/Code_segment

कंप्यूटिंग में, एक कोड खंड, भी एक पाठ खंड या बस के रूप में पाठ के रूप में जाना जाता है, एक भाग के संदर्भ में प्रयुक्त एक मुहावरा है मेमोरी या ऑब्जेक्ट फ़ाइल जिसमें निष्पादन योग्य निर्देश शामिल हैं। इसमें एक निश्चित आकार है और आमतौर पर केवल पढ़ने के लिए है। यदि टेक्स्ट सेक्शन केवल पढ़ने के लिए नहीं है, तो विशेष आर्किटेक्चर कोड स्वयं-संशोधित करने की अनुमति देता है। अगर रीड-ओनली कोड पुनर्वित्त है तो इसे एक ही समय में एक से अधिक प्रक्रिया द्वारा निष्पादित किया जा सकता है। स्मृति क्षेत्र के रूप में, एक कोड सेगमेंट मेमोरी के निचले हिस्सों में या उसके नीचे रहता है ताकि ढेर को रोकने के लिए और स्टैक ओवरफ़्लो ओवरराइटिंग से बचा जा सके।

डाटा के आधार पर विभाजित - .data: http://en.wikipedia.org/wiki/Data_segment

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

बीएसएस: http://en.wikipedia.org/wiki/.bss

कंप्यूटर प्रोग्रामिंग में, .bss या बीएसएस (जो मूल रूप से ब्लॉक प्रतीक द्वारा शुरू किया गया के लिए खड़ा था) कई संकलनकर्ता और एक भाग के नाम के रूप में linkers द्वारा किया जाता है डेटा सेगमेंट में स्थिर चर और वैश्विक चर जो पूरी तरह से शून्य-मूल्यवान डेटा के साथ भरे हुए हैं (यानी, निष्पादन शुरू होने पर)। यह अक्सर को "बीएसएस अनुभाग" या "बीएसएस सेगमेंट" के रूप में जाना जाता है। प्रोग्राम लोडर बीएस अनुभाग से आवंटित स्मृति को प्रारंभ करता है जब यह प्रोग्राम लोड करता है।

रजिस्टर्स, दूसरों द्वारा वर्णित, सीपीयू की सुविधाओं को डेटा या मेमोरी एड्रेस स्टोर करने के लिए बताए गए हैं। ऑपरेशंस पर पंजीकरण किया जाता है, जैसे add eax, ebx और असेंबली बोली के आधार पर, इसका मतलब अलग-अलग चीजें हैं। इस मामले में, यह exx की सामग्री को ईएक्स में जोड़ने और इसे ईएक्स (NASM वाक्यविन्यास) में संग्रहीत करने के लिए अनुवाद करता है। जीएनयू एएस में समतुल्य (एटी & टी) है: movl $ebx, $eax। असेंबली की विभिन्न बोलीभाषाओं में अलग-अलग नियम और ऑपरेटर होते हैं। मैं इस कारण से एमएएसएम का प्रशंसक नहीं हूं - यह NASM, YASM और GNU AS दोनों के लिए बहुत अलग है।

सी एबीआई के नाम से सामान्य बातचीत में वास्तव में कोई कार्रवाई नहीं है कि यह कैसे होता है; उदाहरण के लिए, x86 (यूनिक्स) पर आपको स्टैक पर धक्का दिया गया एक विधि का तर्क मिलेगा, जबकि यूनिक्स पर x86-64 में पहले कुछ तर्क रजिस्टरों में स्थित होंगे। एबीआई दोनों फंक्शन के परिणाम को ईएक्स/रैक्स रजिस्टर में संग्रहीत करने की उम्मीद करते हैं।

यहां 32-बिट एड रूटीन है जो विंडोज और लिनक्स दोनों के लिए इकट्ठा होती है।

_Add 
    push ebp    ; create stack frame 
    mov  ebp, esp 
    mov  eax, [ebp+8] ; grab the first argument 
    mov  ecx, [ebp+12] ; grab the second argument 
    add  eax, ecx  ; sum the arguments 
    pop  ebp    ; restore the base pointer 
    ret 

यहां, आप देख सकते हैं कि मेरा क्या मतलब है। "वापसी" मान ईएक्स में पाया जाता है। इसके विपरीत, x64 संस्करण इस तरह दिखेगा:

_Add 
    push rbp    ; create stack frame 
    mov  rbp, rsp 
    mov  eax, edi  ; grab the first argument 
    mov  ecx, esi  ; grab the second argument 
    add  eax, ecx  ; sum the arguments 
    pop  rbp    ; restore the base pointer 
    ret 

ऐसे दस्तावेज हैं जो इस तरह की चीज़ को परिभाषित करते हैं। यहां यूनिक्स x64 एबीआई है: http://www.x86-64.org/documentation/abi-0.99.pdf। मुझे यकीन है कि आप शायद किसी भी प्रोसेसर, मंच आदि के लिए एबीआई पा सकते हैं।

आप असेंबली में किसी सरणी पर कैसे काम करते हैं?सूचक अंकगणित। eax पर एक बेस एड्रेस दिया गया है, तो अगले संग्रहित पूर्णांक [eax+4] पर होगा यदि पूर्णांक आकार में 4 बाइट्स है। आप मॉलोक/कॉलोक तक कॉल का उपयोग करके यह स्थान बना सकते हैं, या आप मेमोरी आवंटन सिस्टम कॉल को कॉल कर सकते हैं, जो भी आपके सिस्टम पर है।

'ढेर' क्या है? विकिपीडिया के अनुसार, यह गतिशील स्मृति आवंटन के लिए आरक्षित स्मृति का क्षेत्र है। जब तक आप कॉलोक, मॉलोक या मेमोरी आवंटन सिस्टम कॉल नहीं करते हैं, तब तक आप इसे अपने असेंबली प्रोग्राम में नहीं देखते हैं, लेकिन यह वहां है।

निबंध के लिए खेद है।

+0

+1, बहुत उपयोगी, धन्यवाद। एबीआई को जोड़ने के लिए – Cam

+0

+1। –

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