2011-01-09 11 views
5

पर पैरामीटर पास करने के लिए फोर्स जीसीसी फोर्स पर फ़ंक्शन के पैरामीटर को पास करने के लिए जीसीसी को मजबूर करने का कोई तरीका है?स्टैक

मैं पैरामीटर पास करने के लिए रजिस्टरों का उपयोग नहीं करना चाहता हूं।

अद्यतन: से CodeSourcery

+3

रजिस्टरों में पैरामीटर गुजरने का एक बुरी चीज क्यों है? –

+0

यह एक बुरी बात नहीं है। मैं सिर्फ पैरामीटर को इस तरह से पारित करना चाहता हूं क्योंकि मैं // थ्रेड सृजन (और आवंटन ढेर) नियमित रूप से // emulating // emulating। – cojocar

+0

क्या वास्तुकला/एबीआई? – ephemient

उत्तर

0

हाथ-जीसीसी का उपयोग कर I'am के अनुसार: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf

पहले चार रजिस्टरों r0-R3 (A1-ए 4) तर्क मान प्रदान करने के लिए किया जाता है में एक सबराउटिन और परिणाम फ़ंक्शन से मान वापस करने के लिए। वे को नियमित रूप से इंटरमीडिएट मान को नियमित रूप से (लेकिन सामान्य रूप से, केवल सबराउटिन कॉल के बीच) रखने के लिए उपयोग किया जा सकता है।

एआरएम पर, कोई अन्य कॉलिंग सम्मेलन नहीं है, लेकिन डिफ़ॉल्ट, जो मुझे पता है। और यहां क्यों है:

  1. आप क्यों चाहेंगे? आपके फ़ंक्शन को अन्य कार्यों द्वारा संकलित रूप में कॉल करने योग्य नहीं होगा, एक संगतता गड़बड़ पैदा करेगा।
  2. एबीआई का अनुपालन करने वाले सिस्टम फ़ंक्शंस पर आपकी कॉल काम नहीं करेगी, जब तक कि संकलक कॉलिंग सम्मेलनों के बीच अंतर करने में सक्षम न हो। अब, मुझे पता है कि अतीत में x86-32 के लिए अलग-अलग कॉलिंग सम्मेलन हैं, लेकिन ध्यान दें कि x64 कैसे सरल है (एएमडी 64 बनाम जो भी माइक्रोसॉफ्ट ने किया)। क्यों, ARM calling convention डिज़ाइन करते समय, क्या आप कई अलग-अलग कॉलिंग सम्मेलनों की अनुमति देंगे? यह एक संगतता गड़बड़ बनाता है।
+1

हाँ आप सही हैं। यह एक * विषम * चीज है, विशेष रूप से आपके द्वारा बताए गए कारणों के कारण। विचार यह है कि परिभाषित कार्य एक थ्रेड का मुख्य निकाय था - एक कस्टम वातावरण (ओएस) में। कस्टम ओएस ढेर पर धागे के तर्क को धक्का देगा। एबीआई का सम्मान करने के लिए, दो कार्यवाही हैं: तर्क को आर 0 में डालें या घोषित करें * thread_func (uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3, void * param) *। धन्यवाद! – cojocar

+1

फिर भी उन्हें रजिस्टरों में क्यों न रखें? आपको धागे में रजिस्टरों को संरक्षित करने की आवश्यकता होगी, लेकिन आपको वैसे भी करना होगा - कल्पना करें कि आपने निष्पादन के दौरान धागे को स्विच किया है और पुराने फ़ंक्शन के रजिस्टर मान स्थान पर छोड़े गए थे ... यदि ओएस ने ऐसा किया है, तो यह बहुत गन्दा होगा। –

+0

थ्रेड उपयोगकर्तास्थान से बनाया गया है और नए बनाए गए धागे के लिए रजिस्टर मान सेट करने के लिए कोई API (syscall) नहीं है। – cojocar

1

आप संरचनाओं में संरचना को लपेटने का प्रयास कर सकते हैं; वैकल्पिक रूप से

struct my_x_y { 
    int x, y; 
    my_x_y(): x(0), y(0) {} // a non-trivial constructor to make the type non-POD 
}; 

int calc_my_sum(my_x_y x_and_y) { 
    // passing non-POD object by value forces to use the stack 
    return x_and_y.x + x_and_y.y; 
} 

, तो आप सिर्फ रजिस्टरों का उपयोग करने के लिए 4 डमी पैरामीटर जोड़ सकते हैं, इसलिए अन्य पैरामीटर ढेर का उपयोग करेगा:: उदाहरण के लिए, अपने कार्य है अगर int calc_my_sum(int x, int y) {return x+y;} आप इसे इस रूप में बदल सकते हैं (बदसूरत)

struct force_stack_usage { 
    int dummy0, dummy1, dummy2, dummy3; 
} 

int calc_my_sum(force_stack_usage, int x, int y) { 
    return x + y; 
} 
+0

अच्छा हैक! पहला समाधान केवल सी ++ है, मैं यह उल्लेख करना भूल गया कि मुझे सी समाधान की आवश्यकता है। धन्यवाद। – cojocar

+1

आप जो चाहते हैं उसे हासिल करने के लिए एक विचित्र सी ++ कन्स्ट्रक्टर की आवश्यकता नहीं है। सी structs में बस ढेर पर नकल कर रहे हैं। सी 99 में आप 'calc_my_sum ((my_x_y) {.x = 5, .y = 7}) के साथ फ़ंक्शन को कॉल भी कर सकते हैं या समस्या के बिना मैक्रो में ऐसी चीज लपेट सकते हैं। –

0

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

+0

मुझे यकीन नहीं है कि यह प्रश्न को संबोधित कर रहा है या नहीं ... – Nanomurf

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

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