2015-06-16 12 views
7

इसलिए मैंने कुछ समय पहले खुद को x86 असेंबली पढ़ाया और सी ++ में इनलाइन असेंबली के साथ खेल रहा था।फंक्शन में ऐरे वैल्यू बदलना - इनलाइन असेंबली

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

inline void Set(int pArray[], unsigned int pIndex, int pNum) { 
    __asm { 
     mov ebx, pIndex 
     mov eax, 4 
     mul ebx 
     mov ebx, pNum 

     lea edi, pArray 
     mov [ edi + eax ], ebx 
    } 
} 

int main() { 
    int myArray[ 5 ] = { 1, 2, 3, 4, 5 }; 
    Set(myArray, 2, 7); 
    std::cout << myArray[ 2 ] << std::endl; 
} 

तो कोड, सरणी पते के शुरू होने से लोड करना चाहिए सूचकांक हो और 4 इसलिए स्मृति स्थान है कि कई बाइट्स द्वारा ले जाया जाता है से गुणा करें, और उस में भेजे गए मान के लिए बदल जाता है। हालांकि, जब मैं ऐसा करता हूं, मान वही रहता है। ऐसा क्यों है? क्या गलत हो रहा है?

+2

आप शायद 'mov edi, pArray' चाहते हैं अन्यथा आप अपने तर्क चर के पते को लोड कर रहे हैं, जहां यह इंगित कर रहा है। आप खुद को डीबगर का उपयोग करके खुद को पढ़ाना चाहेंगे :) – Jester

+1

यूप। वह समस्या थी। मैंने इसे मूल रूप से एक समारोह से लिखा था जहां सरणी को इसके दायरे में पहुंचा जा सकता था, इसलिए यह काम करता था, लेकिन जब समारोह में encapsulated यह काम करना बंद कर दिया तो यह बहुत समझ में आता है कि मुझे "mov" का उपयोग क्यों करना चाहिए था और नहीं "ली"। धन्यवाद :-) – CMilby

उत्तर

1

lea "प्रभावी प्रभावी लोड" के लिए खड़ा है, आपका ली तर्क के पते को रखता है। आपका मतलब क्या है lea edi, [pArray]

हालांकि, दो और चीजें हैं: 1) आपको चार से गुणा करने की आवश्यकता नहीं है। आप lea edi, [pArray + 4*ebx] कर सकते हैं क्योंकि "स्केल इंडेक्स बाइट" एड्रेसिंग मोड आपको 4 से गुणा करने और तत्काल पता जोड़ने देता है।

2) आप 32 बिट्स मान रहे हैं। 2015 के मध्य में आप किस कंप्यूटर का उपयोग कर रहे हैं अभी भी 32 बिट मोड में काम कर रहा है?

मैं इंटेल वाक्यविन्यास असेंबली पर जंगली हूँ। क्या मैं आपको जीसीसी में असेंबलर और सी ++ कोड के एकीकरण को जानने के लिए सिफारिश कर सकता हूं? https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

+0

1 के लिए, 'ली एडी, [pArray + 4 * ebx] 'मान को नहीं बदलता है। और 2 के लिए, यह एक अच्छा सवाल है। मैं विजुअल स्टूडियो प्रोफेशनल 2010 में हूं और यह मुझे 64-बिट रजिस्टरों का उपयोग करने की अनुमति नहीं देगा। मैंने मूल रूप से 64-बिट रजिस्ट्रार के साथ किया लेकिन त्रुटि C2415 प्राप्त कर रहा था। – CMilby

+0

प्रभावी पता लोड करने की आवश्यकता नहीं है, न ही गुणा निर्देश का उपयोग करने के लिए। चेक क्या जीसीसी संकलक एक्सप्लोरर पता चलता है: http://goo.gl/njHPU3 बस "पैमाने सूचकांक बाइट" इस तरह संबोधित कर का उपयोग करें: 'mov [RDI + RSI * 4], edx' कहाँ RDI है लिनक्स कॉलिंग सम्मेलन में सरणी आधार पता, आरएसआई सूचकांक पैरामीटर है और edx मान है – EdMaster

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