2013-07-18 11 views
20

मैं सी प्रोग्रामिंग भाषा में अभी शुरुआत कर रहा हूँ, हाल ही में मैं कार्यों सीखने शुरू कर दिया है, मैं अध्ययन किया है कि कार्यों कीवर्ड वापसी का उपयोग फोन करने वाले समारोह में एक मूल्य के वापस जाने के लिए। उदाहरण के लिए निम्नलिखित कार्यक्रम।निम्नलिखित सी प्रोग्राम में _AX = 1000 का अर्थ क्या है?

int getVal(){ 
return 1000; 
} 

int main(){ 
int x = getVal(); 
printf("x = %d",x); 
return 0; 
} 

प्रिंट होगा एक्स = 1000

लेकिन मैं उस उलझन में क्यों निम्नलिखित कार्यक्रम एक्स = 1000 भी रूप में उत्पादन का उत्पादन (टर्बो सी संकलक 32 बिट से कम) कर रहा हूँ। कृपया समझाएँ।

int get_val(){ 
_AX = 1000; 
} 

int main(){ 
int x = get_val(); 
printf("x = %d",x); 
return 0; 
} 

उत्तर

23

"वापसी मूल्य" किसी विशेष रजिस्टर ("एबीआई" द्वारा परिभाषित किया गया है, एप्लिकेशन बाइनरी इंटरफेस द्वारा परिभाषित किया गया है, जो बताता है कि कैसे कंपेलरों को अपना कोड उत्पन्न करना चाहिए), अधिकांश x86 सिस्टम में, जो ईएक्स (32 बिट) है या एक्स (16 बिट) [_AX नहीं कह रहा है वास्तव में आंतरिक रूप से ईएक्स है]।

यह कंपाइलर स्पष्ट रूप से _AX नामकरण करके "रजिस्टर" का उपयोग करके समर्थन करता है। तो एक मूल्य के साथ [ई] एक्सएक्स रजिस्टर लोड करके, हम अनिवार्य रूप से इस मूल्य को वापस कर रहे हैं।

यह निश्चित रूप से किसी अन्य कंपाइलर में काम नहीं करेगा, हालांकि इनलाइन असेंबलर एक ही चीज़ प्राप्त कर सकता है।

+0

वाक्यविन्यास काम नहीं करेगा लेकिन अवधारणा काम करता है ... –

12

यहां सी में, _AX एक छद्म रजिस्टर है। और जब आप AX=1000 करते हैं, यह मान 1000 एक्यूमुलेटर

से लिया जाता है लेकिन यह जीसीसी संकलक

संकलित में अपेक्षा के अनुरूप काम नहीं हो सकता है और टर्बो सी में निम्नलिखित कार्यक्रम चलाएं, आप आउटपुट के रूप में 35 मिल जाएगा। यह अन्य कंपाइलरों में काम नहीं कर सकता है।

#include<stdio.h> 
int main() 
{ 
    int a = 0; 
    a = 35; 
    printf("%d"); 
    return 0; 
} 

एक = 1200 का पता मान लें वीडियो स्मृति = 5500 के पते मान लें;

MOV AH, 35 
MOV [1200], AH 
MOV [5500], AH // prints on the screen. 

यह निष्पादन का तरीका है। मूल्य 35 को स्थान 1200 पर कॉपी करने के बाद, एएच मूल्य 35 को बरकरार रखता है।

फिर printf("%d") एएच से मान प्राप्त करने का प्रयास करता है और स्क्रीन पर प्रदर्शित करने के लिए वीडियो मेमोरी भेजता है।

यदि हम printf("%d %d", age, salary) का उपयोग करते हैं, तो वीडियो मेमोरी भेजने के लिए उस मान का उपयोग करने से पहले आयु का मूल्य एएच में स्थानांतरित किया जाता है। फिर वेतन का मूल्य एएच में ले जाया जाता है और फिर वीडियो मेमोरी को भेज दिया जाता है।

मान लें, आयु का पता = 1200; वेतन का पता = 1202; वीडियो मेमोरी = XXXX का पता; (यह कोई के अनुसार बदला जाएगा। स्क्रीन पर मुद्रित वर्ण की, न इस पते मूल्य के बारे में ज्यादा लगता है)

MOV AH, [1200] 
MOV [XXXX], AH 
MOV AH, [1202] 
MOV [XXXX], AH 

मुझे आशा है कि इस कार्यक्रम के लिए दिए गए समाधान समझने में मदद मिलेगी।

+1

आहा यह मुझे कॉलेज दिवस प्रोग्रामिंग की याद दिलाता है, संचयक उपयोग देखता है क्योंकि कॉलिंग फ़ंक्शन पर नियंत्रण लौटने पर तुरंत वापसी मूल्य आवंटित किया जाता है, इसलिए जीसीसी भी 'ए' रजिस्टर का उपयोग करता है। लेकिन बात यह कोड है (सिंटैक्स-वार) जीसीसी कंपाइलर द्वारा समर्थित नहीं है। सी में असेंबली कोड लिखना इनलाइन-असेंबली कहा जाता है, और इसके कंपाइलर आश्रित (सिंटैक्स में भी) –

+1

@ ग्रिजेश चौहान: जो आप जानते हैं उसे साझा करना प्राइम फैक्टर सर, वोट और प्रतिनिधि माध्यमिक हैं! –

+0

आह मैं एक और चीज़ साझा करना भूल गया, जीसीसी द्वारा संकलित निष्पादन योग्य को अलग करने की कोशिश करें ('objdump exename' का उपयोग करके) या संकलित असेंबली कोड ('gcc -S code.c') प्राप्त करें और वापसी के लिए रजिस्टर की जांच करें। –

7

टीसी संकलक (32 बिट) के अनुसार, एक समारोह के दिए गए मान एक्यूमुलेटर (एसी) में जमा हो जाती है, और यह _AX का उपयोग कर टीसी संकलक में पहुँचा जा सकता है, इसलिए जब आप लिखते हैं:

_AX = 1000; 

इसका मतलब है कि आप Accumulator के अंदर मूल्य 1000 रख रहे हैं, और जब फ़ंक्शन इसके निष्पादन को पूरा करता है और नियंत्रणकॉलर फ़ंक्शन पर पहुंचता है, तो Accumulator का मान चेक किया जाता है, और इस मामले में यह मान x में संग्रहीत किया जाएगा।

यहाँ

बयान

x = get_val(); 

बस

x = 1000; 

होगा लेकिन यह केवल अपने मामले में हो सकता है, में (टीसी 32 बिट विंडोज़ संकलक), यह या के लिए काम नहीं हो सकता है इसका मतलब है अन्य कंपाइलर्स।

+0

मुझे आश्चर्य है कि क्या बोर्लैंड अभी भी सी ++ बिल्डर के साथ इसकी अनुमति देता है? जब इसे पहली बार रिलीज़ किया गया था, तो मैक पीपीसी सीपीयू पर चल रहे थे, जिनमें कोई एक्स, ईएक्स, आदि रजिस्ट्रार नहीं है ... –

0

गेटवाल() में, 1000 को संचयक में संग्रहीत किया जाता है, और गेटवाल() संकलन समय चेतावनी देगा कि फ़ंक्शन को एक मान वापस करना चाहिए, फिर मुख्य में, x को वापस किए गए मान को आवंटित किया जाएगा या जमाकर्ता में संग्रहीत किया जाएगा 1000, यही कारण है कि यह x = 1000 प्रिंट करेगा।

+0

ध्यान दें कि संचयक एक सीपीयू रजिस्टर है और आपको भाग्य 1000 परिणाम मिल रहा है। –

+0

तो यह भाग्य से क्यों हो रहा है ... क्या आप बता सकते हैं, तो हम में से कई को इसके बारे में पता चल जाएगा ... – akay

+0

लिनक्स 64 बिट कंपाइलर एक्सप्लोरर पर यह दिखाता है: https://godbolt.org/g/R8ggW9 । आप देख सकते हैं कि सही वापसी के लिए मूल्य ईएक्स में संग्रहीत किया जाता है। बिना किसी वापसी के संस्करण में ईएक्स में जो भी मूल्य है, वह उठाएगा। यह अंतिम मूल्य इस्तेमाल किया जा सकता है, या यह मूल्य पर कुछ 'यादृच्छिक' छोड़ा जा सकता है। –

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