2009-08-19 16 views
16

मैं assermbly जानने के लिए (ताकि मेरे साथ सहन) कोशिश कर रहा हूँ और मैं इस लाइन पर एक संकलन त्रुटि हो रही है:विधानसभा: दो स्मृति के बीच चलती के पते

mov byte [t_last], [t_cur] 

त्रुटि

error: invalid combination of opcode and operands 
है

मुझे लगता है कि इस त्रुटि के कारण एक mov अनुदेश दो स्मृति पतों के बीच ले जाने के लिए बस है कि इसके लिए संभव नहीं है, लेकिन googling के आधे घंटे और मैं इस बात की पुष्टि करने में सक्षम नहीं किया गया है - यह मामला है?

mov cl, [t_cur] 
mov [t_last], cl 

सिफारिश रजिस्टर का उपयोग करने के क्या (या मैं ढेर के बजाय का उपयोग करना चाहिए):

इसके अलावा, यह सोचते हैं मैं सही है कि मैं को कॉपी स्मृति के लिए एक मध्यवर्ती बिंदु के रूप में एक रजिस्टर उपयोग करने की आवश्यकता का मतलब कर रहा हूँ?

+3

कभी कभी बेहतर है * * स्रोत के लिए जाने के बजाय googling उदाहरण के लिए यहाँ, इंटेल 64 और IA-32 निर्देश हूं, जहां 'mov' के लिए संकार्य संयोजनों को देख सकते है की जरूरत है , http://www.intel.com/Assets/PDF/manual/253666.pdf –

+0

वहाँ नियम है कि एक अनुदेश दो स्मृति ऑपरेंड नहीं ले जा सकते करने वाले हैं अपवाद; देखना [यहां] (http://stackoverflow.com/questions/14510280/why-cant-mov-have-both-operands-as-memory-locations?lq=1#comment20229305_14510280)। – legends2k

उत्तर

21

आपका संदेह सही है, तो आप याद करने के लिए स्मृति से स्थानांतरित नहीं कर सकते।

किसी भी सामान्य प्रयोजन रजिस्टर करना होगा। यदि आप सुनिश्चित नहीं हैं कि इसके अंदर क्या है और इसे एक बार वापस करने के लिए इसे पुनर्स्थापित करने के लिए रजिस्टर को पुश करना याद रखें।

+0

क्या डेटा को खुद को ढेर पर धक्का देने के लिए एक रजिस्टर का उपयोग करने का कोई फायदा है? – Justin

+2

स्टैक से पॉपिंग पर और बाद में पॉपिंग दो अतिरिक्त मेमोरी एक्सेस जोड़ता है। – hirschhornsalz

3

वहाँ भी स्मृति के लिए स्मृति से डेटा ले जाने से एक MOVs आदेश दिया गया है:

 push  di 
    push  si 
    push  cx 
    mov  cx,(number of bytes to move) 
    lea  di,(destination address) 
    lea  si,(source address) 
    rep  movsb 
    pop  cx 
    pop  si 
    pop  di 

नोट:: धक्का & पॉप्स हैं

MOV SI, OFFSET variable1 
MOV DI, OFFSET variable2 
MOVS 
+0

काम करेगा, लेकिन इसे अतिरिक्त देखभाल की आवश्यकता है: आपको si और di registers को सहेजने की आवश्यकता है। मुझे लगता है कि एक बाइट की प्रतिलिपि बनाने के लिए यह इसके लायक नहीं है। – sharptooth

+5

x86 पर स्ट्रिंग कमांड अप्रचलित माना जा सकता है। कभी उनका इस्तेमाल न करें। वे "हाथ से" की प्रतिलिपि बनाने से कभी तेज़ नहीं होते हैं, लेकिन ज्यादातर मामलों में बहुत धीमे होते हैं। – hirschhornsalz

+0

@hirschhornsalz, necromance के लिए खेद है, लेकिन क्या आपके पास स्ट्रिंग कमांड अनिवार्य रूप से अप्रचलित होने के बारे में कोई विस्तृत जानकारी है? –

4

यह 16 बिट में वास्तव में आसान है, बस निम्न कार्य करें अगर आपको रजिस्टरों की सामग्री को सहेजने की ज़रूरत है तो निरंतर।

+0

+1, क्योंकि कुछ परिस्थितियों में आपके टूलबॉक्स में सभी टूल्स जानना अच्छा होता है।rep movsb/movsw 1 बाइट ऑपकोड हैं, आईआईआरसी –

+0

आर्किटेक्चर के आधार पर, आप सभी रजिस्टरों को अलग-अलग पॉप करने और उन्हें पॉप करने की बजाय पॉप को धक्का देने के बजाय पुश का उपयोग कर सकते हैं। – BalinKingOfMoria

+0

यह 32 और 64 बिट में भी काम करता है, सिवाय इसके कि यह उस बिट सिस्टम – Rahly

-2

बस आप के साथ "स्मृति बाधा" के बारे में बात करना चाहते हैं। ग कोड

a = b; 

में

mov %eax, a # suppose %eax is used as the temp 
mov b, %eax 

प्रणाली के लिए इकट्ठा किया जाएगा असाइनमेंट की atomicity गारंटी नहीं दे सकते। यही कारण है कि हम एक RMB (अवरोध पढ़ें)

+0

x86 के लिए रजिस्टरों का उपयोग करता है, परमाणु रूप से मेमोरी से स्मृति तक प्रतिलिपि नहीं बना सकता है। बाधाएं परमाणुता नहीं बनाती हैं, वे केवल बाधा के आधार पर (समय या रन-टाइम या दोनों संकलित) को रोकते हैं। –

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