2011-11-07 11 views
6

पर असेंबली में आउटपुटिंग पूर्णांक यह शुद्ध असेंबली (यानी कोई पुस्तकालय या सी को कॉल) में किया जाना चाहिए।लिनक्स

मैं समस्या का सार समझता हूं: किसी को पूर्णांक को 10 से विभाजित करने की आवश्यकता होती है, एक अंकों को शेष ASCII में परिवर्तित करना होता है, आउटपुट होता है और फिर प्रक्रिया को दोहराया जाता है।

लेकिन किसी कारण से, यह अभी काम नहीं कर रहा है। मैं x86 पर NASM का उपयोग कर रहा हूँ।

यहाँ है कि मैं क्या किया है है के लिए अब (नहीं उत्पादन कुछ भी करता है, लेकिन किसी भी कोडांतरक त्रुटियों या तो फेंक नहीं है):

; integer to output is stored in eax 
mov ecx, 10 ; for base 10 

loop: 
div ecx ;EAX contains the quotient, EDX the remainder 

; Do something to EDX to convert it to ASCII, not sure if this is correct 
add edx, '0' 

push eax ;We'll be playing with EAX to output EDX, save EAX to the stack 

mov eax, 4    ; sys_write 
mov ebx, 1    ; to STDOUT 
mov ecx, edx 
mov edx, 1 
int 0x80 

pop eax ;restore EAX 

cmp eax, 0 ;If EAX is 0, our job is done 
jnz loop 

इस एक (यानी, this के समान सवालों की एक संख्या हैं और this), लेकिन मैं कार्यान्वयन में खो गया हूँ। This question (डॉस के लिए) भी सहायक था, लेकिन मैं अभी भी उलझन में हूं।

मुझे यहां कुछ याद आना चाहिए। विचार?

+0

मुझे इस कोड में कहीं भी '10' नहीं दिखाई देता है, जो दशमलव अंकों को मुद्रित करने के लिए आवश्यक होगा। (आपको '10' के साथ बार-बार 'div' और' mod' की आवश्यकता है, अंकों को संग्रहित करें, उन्हें उलट दें, और उन्हें आउटपुट करें या पहले 'बड़े अंत' से जाएं, और' 100,000,000' से विभाजित करें, फिर '10,000,000' , आदि - लेकिन यह स्टोर-एंड-रिवर्स विधि से कम जटिल नहीं हो सकता है।) – sarnold

+0

@ कर्नाल्ड शीर्ष पर एक पंक्ति शामिल करना भूल गए। इसे जोड़ने के लिए मेरे प्रश्न को संपादित किया। –

+0

बढ़िया! अद्यतन के लिए धन्यवाद। – sarnold

उत्तर

3

कम से कम दो और समस्याएं हैं। ecx के भ्रष्टाचार है कि उल्लेख किया @sarnold परे:

  1. div ecx, ecx द्वारा 64-बिट मूल्य edx:eax बिताते हैं ताकि आप सुनिश्चित करने के लिए आप विभाजन से पहले 0 के edx सेट कि जरूरत है।

  2. write सिस्टम कॉल (ecx में) का दूसरा तर्क उस वर्ण में एक पॉइंटर होना चाहिए जिसमें वह चरित्र है जिसे आप मुद्रित करना चाहते हैं, चरित्र नहीं। दूसरी समस्या को हल करने

एक तरह से चरित्र आप ढेर पर प्रिंट करना चाहते हैं रजिस्टर पुश करने के लिए, और फिर सबसे हाल ही में धक्का दे दिया आइटम पर especx को (ढेर सूचक अंक ढेर सूचक आवंटित , और x86 स्टोर छोटे-एंडियन मानते हैं, इसलिए पहला बाइट कम 8 बिट्स है)। जैसे

push edx   ; save value on stack 
mov eax, 4  ; sys_write 
mov ebx, 1  ; to STDOUT 
mov ecx, esp ; first byte on stack 
mov edx, 1  ; length = one byte 
int 0x80 
pop edx   ; remove what we pushed (or "add esp, 4" would do just as well here; 
       ;      we don't need the actual value again) 

कुछ उत्पादन करने के लिए पर्याप्त होना चाहिए कि ...

(लेकिन उस बिंदु पर, आप अपने एल्गोरिथ्म के एक "सुविधा" दिखाई दे सकता है, और फिर से सोचने के लिए आप कैसे अंक की दुकान चाहते हैं जो विभाजन द्वारा उत्पादित होते हैं!)

+0

यह एक महान स्पष्टीकरण है, इसे स्पष्ट करने के लिए धन्यवाद। जैसा कि आप संकेत देते हैं, मैं समझता हूं कि यह एल्गोरिदम क्यों विपरीत में पूर्णांक प्रिंट करता है। इसे ठीक करने पर कोई विचार? –

+1

अंकों के लिए कुछ जगह रिजर्व करें (सबसे बड़ा हस्ताक्षर 32-बिट पूर्णांक 42 9 4 9 672 9 5 है, इसलिए 10 बाइट पर्याप्त है), या तो डेटा सेक्शन में (उदाहरण के लिए 'resb' निर्देश का उपयोग करके) या स्टैक पर (केवल' esp' से घटाएं) , लेकिन सुनिश्चित करें कि स्टैक को सही ढंग से गठबंधन रखने के लिए आप 4 का एक से अधिक घटाएं)। फिर या तो अंकों को बफर में आगे बढ़ें, फिर प्रत्येक चरित्र को रिवर्स प्रिंट करने में बफर पर लूप करें; या (बेहतर?) बफर के अंतिम बाइट से शुरू होने वाले बफर में अंकों को संग्रहित करें और पीछे की ओर काम कर रहे हों, फिर आप सभी अंकों को एक 'लिखने' syscall के साथ लिख सकते हैं। –

2

आप ठीक से अपनी दिनचर्या के शीर्ष पर 10 को ecx निर्धारित करते हैं, लेकिन बाद में ecx के ऊपर लिख:

mov eax, 4    ; sys_write 
mov ebx, 1    ; to STDOUT 
mov ecx, edx ;;; oops -- lost the 10 
mov edx, 1 
int 0x80 

loop एक अप लाइन ले जाने का प्रयास है, तो ecx10 हर बार लूप के माध्यम से फिर से आरंभ नहीं हो जाता ।

+0

अच्छी पकड़, इसे ठीक किया गया। मुझे अभी भी कोई आउटपुट नहीं मिल रहा है, मेरा अनुमान है कि 'एडैक्स जोड़ें,' 0'' सही ढंग से एकल अंक को दशमलव में परिवर्तित नहीं कर रहा है। –

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

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