2010-02-05 22 views
13

मैं के रूप में कोड लिखा है अब तक:x86 असेंबली भाषा में लूप कैसे बनाएं?

.code 

main 
Clrscr 

    mov dh,10   ;row 10 

    mov dl,20   ;column 20 

    call Gotoxy   ;locate cursor 

    PromptForIntegers 

    WriteString  ;display string 
    ReadInt   ;input integer 
    ArraySum 

    WriteString  ;display string 
    WriteInt   ;display integer 

DisplaySum ENDP 

END main 

मैं कैसे प्रत्येक पाश यात्रा के बाद स्क्रीन को साफ करने के लिए, यह उन्हीं चरणों का एक पाश का उपयोग कर तीन बार दोहराने के लिए मिलता है?

+5

कहाँ इन मैक्रो ('WriteInt',' WriteString') से आया? x86 असेंबली इन दिनों बेस्टर्डिज्ड है। –

+0

यह असेंबली भाषा क्या है? http://en.wikipedia.org/wiki/List_of_programming_languages_by_category#Assembly_languages ​​ – Dolph

+2

@mmyers: आर्किटेक्चर टैग को हटाने के साथ क्या है? विधानसभा में वह * मायने रखता है। – dmckee

उत्तर

2

छोरों

 
mov cx, 3 
startloop: 
    cmp cx, 0 
    jz endofloop 
    push cx 
loopy: 
    Call ClrScr 
    pop cx 
    dec cx 
    jmp startloop 
endofloop: 
    ; Loop ended 
    ; Do what ever you have to do here 

यह केवल लूप के आसपास 3 बार ClrScr बुला, धक्का CX ढेर पर रजिस्टर, 0 की तुलना में, कूद अगर ZeroFlag तो सेट कर दिया जाता endofloop के लिए कूद गिनती करने के लिए CX रजिस्टर का प्रयोग करें। ध्यान दें कि लूप के प्रवाह को बनाए रखने के लिए सीएक्स की सामग्री को ढेर पर/बंद कर दिया गया है।

+1

कुछ अनुकूलन: (1) आप 'cmp cx, 0' और' jz लेबल' के बजाय 'jcxz लेबल' का उपयोग कर सकते हैं। (2) आप 'dec cx' और' jnz लेबल' –

+0

@PA के बजाय 'लूप लेबल' का उपयोग कर सकते हैं: आपके प्रोसेसर, 'jcxz लेबल' और' cmp/jz' के आधार पर समकक्ष हैं। हालिया x86 प्रोसेसर एक चक्र चक्र में सीएमपी/जेएमपी निर्देशों को गठबंधन करने के लिए मैक्रो-फ़्यूज़न का उपयोग करता है, जो अनिवार्य रूप से फ्लाई पर 'jcxz' व्यवहार को दोहराता है। –

+0

यह लूप अविश्वसनीय रूप से अक्षम है। यदि एक लूप शून्य बार चला सकता है, तो लूप के बाहर काउंटर का परीक्षण करें। फिर लूप के अंत में एक सशर्त शाखा का उपयोग करें। और एक रजिस्टर का उपयोग करें जिसे आपको अपने लूप वैरिएबल के रूप में पुश/पॉप करने की आवश्यकता नहीं होगी। (उदाहरण के लिए कॉल-संरक्षित रजिस्टर (ई/आर) बीएक्स या (ई) सी यदि आपके लूप में फ़ंक्शन कॉल हैं।)। और जेफ बी सही है: इंटेल हैसवेल जैसे आधुनिक CPUs पर 'jmpxz' से 'cmp/jz' या' dec/jz' * सस्ता * है। Http://agner.org/optimize/ –

0

आपको सशर्त jmp कमांड का उपयोग करने की आवश्यकता है। यह वही वाक्यविन्यास नहीं है जैसा आप उपयोग कर रहे हैं; MASM की तरह लग रहा है, लेकिन यहां गैस का उपयोग कर एक उदाहरण कुछ कोड से मैं gcd गणना करने के लिए लिखा था है:

gcd_alg: 
    subl %ecx, %eax  /* a = a - c */ 
    cmpl $0, %eax  /* if a == 0 */ 
    je  gcd_done  /* jump to end */ 
    cmpl %ecx, %eax  /* if a < c */ 
    jl  gcd_preswap  /* swap and start over */ 
    jmp  gcd_alg   /* keep subtracting */ 

असल में, मैं cmpl अनुदेश (लंबी तुलना) के साथ दो रजिस्टरों की तुलना करें। यदि यह कम है तो जेएल (कूद कम) निर्देश प्रीपेड स्थान पर कूदता है, अन्यथा यह उसी लेबल पर वापस कूदता है।

स्क्रीन साफ़ करने के लिए, यह उस सिस्टम पर निर्भर करता है जिसका आप उपयोग कर रहे हैं।

+0

'सब% ecx,% eax' परिणाम शून्य होने पर पहले से ही ZF सेट करता है, आपको 'cmp $ 0,% eax' की आवश्यकता नहीं है। और आपको लूप के अंत में दूसरी तरफ शाखा की संरचना करनी चाहिए: 'jnl gcd_alg'/else' gcd_preswap' में आती है। असल में, झंडे अभी भी 'उप' से सेट हैं, इसलिए आप gcd_preswap' में 'sub% ecx,% eax/jnl gcd_alg/je gcd_done/fall-through कर सकते हैं, इसलिए मुख्य लूप दो निर्देश हैं। या यदि 'ए' 'c' से कई गुना अधिक हो तो शेष प्राप्त करने के लिए div का उपयोग करें। –

16
mov cx,3 

loopstart: 
    do stuff 
    dec cx   ;Note: decrementing cx and jumping on result is 
    jnz loopstart ;much faster on Intel (and possibly AMD as I haven't 
        ;tested in maybe 12 years) rather than using loop loopstart 
+4

आप 'डीसी सीएक्स' और' जेएनजे लूपस्टार्ट 'के बजाय' लूप लूपस्टार्ट 'का उपयोग कर सकते हैं जब तक' डू स्टफ 'सीएक्स रजिस्टर –

+5

@PA को संरक्षित करता है: यदि आप' लूप 'का उपयोग नहीं करते हैं तो भी सीएक्स को संरक्षित करना आवश्यक है। –

+1

यह बिल्कुल सही है क्योंकि प्रश्न * तीन * बार लूपिंग के बारे में है। हालांकि, प्रश्न का शीर्षक बहुत अधिक सामान्य है और मुझे लगता है कि यह जोड़ने के लिए उपयोगी हो सकता है, यदि सीएक्स मान एक चर से आया है, स्थिर नहीं, एक जेबीई शून्य निर्देश, लूप में प्रवेश करने से पहले लूपेंड पर कूदने के लिए, जरूरत है। –

9

फिर भी एक और विधि लूप अनुदेश उपयोग कर रहा है:

mov cx, 3 

myloop: 
    ; Your loop content 

    loop myloop 

पाश अनुदेश स्वचालित रूप से cx decrements, और केवल cx अगर कूदता = 0. वहाँ भी LOOPE हैं, और LOOPNE वेरिएंट, आप अगर अपने लूप के लिए जल्दी बाहर तोड़ने के लिए कुछ अतिरिक्त जांच करना चाहते हैं।

आप अपने पाश दौरान cx ​​संशोधित करने के लिए चाहते हैं, पाश सामग्री से पहले ढेर पर इसे पुश करने के लिए सुनिश्चित करें, और इसे बंद पॉप के बाद:

mov cx, 3 

myloop: 
    push cx 
    ; Your loop content 
    pop cx 

    loop myloop 
+0

मदद – user267288

+0

'लूप' [धीमा है, और इसका उपयोग करना एक अच्छी आदत नहीं है] के लिए धन्यवाद [http: // stackoverflow।com/प्रश्न/35742570/क्यों-है-लूप-निर्देश-धीमी गति से सके-इंटेल-है-कार्यान्वित यह कुशलता से)। अगर आपको अपने लूप के अंदर कुछ के लिए एक्सेल की आवश्यकता है (उदाहरण के लिए एक शिफ्ट निर्देश), तो बस लूप काउंटर के लिए एक अलग रजिस्टर का उपयोग करें। लूप-काउंटर निर्भरता श्रृंखला में पुश/पॉप होने के कारण सिर्फ मूर्खतापूर्ण है। आम तौर पर लूप को किसी प्रकार की प्रेरण चर की आवश्यकता होती है, इसलिए बस इसका परीक्षण करें। जैसे लूप के माध्यम से हर बार 4 से एक सूचक, और लूप स्थिति के रूप में एक अंत सूचक के खिलाफ 'cmp/jb' वृद्धि। –

0

मैं एक ही जवाब & लिए देख रहा था इस जानकारी पाया विकि उपयोगी से: लूप निर्देश

पाश अनुदेश ECX decrements और पता आर्ग द्वारा निर्दिष्ट करने के लिए कूदता है, जब तक कि decrementing ECX वजह से अपने मूल्य शून्य हो गया है। उदाहरण के लिए:

mov ecx, 5 
start_loop: 
; the code here would be executed 5 times 
loop start_loop 

लूप कोई झंडे सेट नहीं करता है। अगर उनकी हालत संतुष्ट हो जाता है (जो है, एक विशिष्ट ध्वज सेट है)

loopx आर्ग

ये पाश निर्देश घटती ECX और पता आर्ग द्वारा निर्दिष्ट करने के लिए कूद, जब तक ECX decrementing के लिए अपने मूल्य के कारण होता है शून्य बनो

  • loope पाश अगर बराबर

  • loopne पाश नहीं तो बराबर

  • loopnz पाश नहीं तो शून्य

  • loopz पाश अगर शून्य

स्रोत: X86 Assembly, Control Flow

+0

काम करता है, लेकिन 'dec/jnz' से धीमा है। –

0
.model small 
.stack 100h 
.code 
Main proc 
Mov cx , 30 ; //that number control the loop 30 means the loop will 
;excite 30 time 
Ioopfront: 
Mov ah , 1 
Int 21h 
Loop loopfront; 

इस कॉड 30 चरित्र ले जाएगा

+2

यह क्या जोड़ता है जो पहले से पोस्ट किए गए अन्य उत्तरों में पहले से ही समझाया नहीं गया था? – Michael

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