मैं स्टैक को नहीं समझ सकता कि कैसे काम करता है। मैं उलझन में हूं कि मैं पढ़ता हूं लेकिन मेरा दिमाग इसे प्राप्त नहीं कर सकता है। इसे बिट के साथ करना है। मुझे यकीन नहीं है कि मैं सही हूं, लेकिन स्टैक में "स्थिति" 2 हो जाती है और 2 क्योंकि यह 2*8बिट्स है इसलिए यह तीसरे तत्व को लेने के लिए [6] डालता है? मुझे यकीन नहीं है कि अगर आप मुझे कोड के इस हिस्से की व्याख्या कर सकते हैं तो मैं बहुत अच्छा होगा।

SUM_PIN PROC NEAR   ;it starts the routine
V1: MOV BP,SP       ;SP moves to BP.As far as i remember BP is down on stack                            

V2: MOV AX,0        ;AX takes the 0       

V3: MOV BX,[BP+6]          ;it has something to do with 2 bit but i didn't catch it

V4: MOV CX,[BP+4]                         

V5: MOV DL,[BX]

V6: MOV DH,0
    ADD AX,DX

V7: INC BX   ;increase BX 

V8: LOOP V5   ;go back at V5

v9: MOV BX,[BP+2]

v10:MOV [BX],AX

V11:RET   ; return

SUM_PIN ENDP ;end
-1
m.s 8 जिंदा 2018, 20:31

2 जवाब

सबसे बढ़िया उत्तर

मुझे असेंबली किए हुए काफी समय हो गया है, और यह x86 फ्लेवर था ... लेकिन मैं आपको इसके माध्यम से चलने की कोशिश करूंगा (कुछ अनुमानों के साथ)

SUM_PIN PROC NEAR   ;it starts the routine
V1: MOV BP,SP       ;SP moves to BP.As far as i remember BP is down on stack                            

यह बीपी रजिस्टर में स्टैक पॉइंटर के मूल्य को लोड करता है

V2: MOV AX,0        ;AX takes the 0       

कुल्हाड़ी = 0

V3: MOV BX,[BP+6]          ;it has something to do with 2 bit but i didn't catch it

बीएक्स को उस मान के साथ लोड करें जो बीपी इंगित करता है उससे छह बाइट्स ऊपर है। चूंकि 'एमओवी बीपी, एसपी' के बाद से बीपी को संशोधित नहीं किया गया है, यह "वर्तमान स्टैक स्थान के ऊपर छह बाइट्स" जैसा ही है।

V4: MOV CX,[BP+4]                         

सीएक्स को उस मान के साथ लोड करें जो स्टैक के नीचे से चार बाइट्स ऊपर है। "लूप" कमांड स्वचालित रूप से इस मान को कम कर देगा, और जब सीएक्स 0 . तक पहुंच जाएगा तो "पास" हो जाएगा

V5: MOV DL,[BX]

बीएक्स द्वारा इंगित पते से मूल्य के साथ डीएल लोड करें

V6: MOV DH,0
    ADD AX,DX

कुल्हाड़ी = कुल्हाड़ी + डीएल

V7: INC BX   ;increase BX 

एक को BX में जोड़ें (अगले बाइट पर जाएँ जिसे BX इंगित करता है)

V8: LOOP V5   ;go back at V5


v9: MOV BX,[BP+2]

फ़ंक्शन के अंतिम पैरामीटर से मान के साथ बीएक्स लोड करें (बीपी == एसपी == बॉटम-ऑफ-स्टैक == पता जब आरईटी कहा जाता है)

v10:MOV [BX],AX

AX को BX द्वारा बताए गए पते पर स्टोर करें

V11:RET   ; return
SUM_PIN ENDP ;end

इसे समझने की कुंजी यह है कि स्टैक नीचे बढ़ता है। इसलिए यदि आप स्टैक पर दो-बाइट मान पुश करते हैं, तो SP = SP - 2

यह जानकर और इस कोड को पढ़कर, मैं बता सकता हूं कि [बीपी + 4] 2-बाइट मान था। और मुझे लगता है कि [बीपी + 6] बाइट्स की एक सरणी के लिए एक सूचक है।

इसके लिए C/C++ सिग्नेचर को इस प्रकार पढ़ा जा सकता है (कुछ इस तरह):

void SUM_PIN(byte* first, int someValueThatIsNotUsed, int *total)

तो मुझे लगता है कि सी/सी ++ संस्करण कुछ ऐसा होगा:

void SUM_PIN(byte* first, int count, int *total) {
        int A = 0;
        byte *b = first;

    while (count-- > 0) {
            a = a + *b
            b = b + 1
        }

        return a
    }

संपादित करें: टिप्पणियों के आधार पर, सीएक्स का स्वचालित रूप से एएल "स्वाद" की एक विशेषता के रूप में मूल्यांकन किया जा रहा है जिसे मैं या तो भूल गया था या इसके बारे में पता नहीं था। मैंने इसे प्रतिबिंबित करने के लिए अपने फॉर-लूप को संशोधित किया है

-1
theGleep 9 जिंदा 2018, 00:40

"स्टैक" साधारण कंप्यूटर मेमोरी है, जो इसे उपयोग की शैली से "स्टैक" बनाती है। x86-16 "16 बिट वास्तविक मोड" में वर्तमान "स्टैक का शीर्ष" पता ss:sp है। जैसे ss=0x1234:sp=0x5678 का मतलब भौतिक मेमोरी एड्रेस 0x179B8 को "टॉप ऑफ द स्टैक" कहा जाता है।

यदि आप call near SUM_PIN करेंगे, तो call के बाद अगले निर्देश के पते का 16 बिट ऑफ़सेट स्टैक में जमा हो जाएगा (जैसे push offset <return_address>), यानी दो को sp = से घटाया जाता है। > sp=0x5676, और उस मेमोरी में रिटर्न एड्रेस ऑफ़सेट शामिल है (यह 16 बिट्स है, इसलिए इसके लिए 1234:5676 और 1234:5677 मेमोरी सेल का उपयोग किया जाएगा)।

अब SUM_PIN के अंदर bp को sp पर सेट किया गया है, इसलिए यह उसी मेमोरी को संबोधित करेगा (ss:bp उस वापसी पते की ओर इशारा करते हुए)। bp+2 उससे आगे इंगित करें, इसलिए जो कुछ भी SUM_PIN सबरूटीन कह रहा था, उसे तर्क डेटा को स्टैक मेमोरी में रखना चाहिए था।

कोड उपयोग से इसे उदाहरण के लिए इस तरह कहा जा सकता है:

push offset <some_unsigned_byte_array_label>
push <length_of_array>
push offset <some_label_to_spare_word_memory_to_store_result>
call SUM_PIN
; read result of the subroutine from memory into ax
mov  ax, [some_label_to_spare_word_memory_to_store_result]

SUM_PIN के अंदर ss:bp+2 पिछले push से मान तक पहुंच जाएगा (मेमोरी एड्रेस की ऑफसेट, जहां परिणाम लिखा जाना चाहिए), ss:bp+4 दूसरे पुश स्टोरेज नंबर तक पहुंच जाएगा सरणी में तत्व, और ss:bp+6 पहले पुश तक पहुंचेंगे, जो कि कुछ सरणी के पते की भरपाई है।

सुनिश्चित करें कि आप समझते हैं कि किस मामले में डिफ़ॉल्ट सेगमेंट रजिस्टर का उपयोग किया जाता है, जब [bp+displacement] एड्रेसिंग का उपयोग किया जाता है, तो डिफ़ॉल्ट सेगमेंट रजिस्टर ss होता है, इस प्रकार mov cx,[bp+4] जैसे निर्देश मेमोरी की सामग्री प्राप्त करेंगे ss खंड, लेकिन फिर mov dl,[bx] आधार रजिस्टर के रूप में bx का उपयोग करके डिफ़ॉल्ट खंड ds है, इसलिए यह वर्तमान ds मान के साथ स्टैक से ऑफसेट फ़ेच का विस्तार करेगा भौतिक स्मृति पते की गणना करें।

स्टैक मेमोरी के बारे में कुछ खास नहीं है, सिवाय इसके कि आपके पास कई निर्देश हैं जो इसके साथ परोक्ष रूप से काम करते हैं (push, pop, call, ret, enter, leave, pushf, popf, ...), और 16 बिट रियल-मोड में "OS" (इंटरप्ट) स्टैक को उपयोगकर्ता ऐप के साथ साझा करता है, इसलिए नीचे दिए गए मान ss:sp टाइमर/कीबोर्ड/द्वारा प्रति सेकेंड कई बार ओवरराइट किए जाते हैं... वहां रिटर्न एड्रेस और संरक्षित रजिस्टर मानों को संग्रहीत करने में बाधा आती है, यानी आप अपने मूल्यों को विश्वसनीय रूप से स्टोर करने के लिए उस मेमोरी का उपयोग नहीं कर सकते हैं।

और ss:sp के ऊपर/पर मान ओवरराइट करने से वर्तमान में स्टैक में मौजूद मान ओवरराइट हो जाएंगे, इसलिए यह मानों को संग्रहीत करने के लिए बिल्कुल सही जगह नहीं है। लेकिन अगर आप पहले sub sp,40 जैसा कुछ करके स्टैक में जगह "आरक्षित" करते हैं, तो आप उस स्थान sp+0 .. sp+39 का सुरक्षित रूप से उपयोग कर सकते हैं (अब इंटरप्ट अपने मूल्यों को वर्तमान sp से नीचे संग्रहीत करेगा), और फिर sp को add sp,40 की तरह वापस बहाल करके इसे "रिलीज़" करें।

कुल मिलाकर आपको कुछ डिबगर (emu8086 में एक) का उपयोग करना चाहिए, ss:sp क्षेत्र में स्मृति दृश्य खोलें, और देखें कि push/call निर्देशों का उपयोग करके स्मृति में मान कैसे विकसित हो रहे हैं, और कैसे sp चल रहा है अन्य निर्देशों द्वारा उस क्षेत्र में ऊपर/नीचे।

0
Ped7g 8 जिंदा 2018, 21:05