2010-01-18 23 views
7

पृष्ठभूमि: मुझे Unitech HT630 के लिए डेटा संग्रह प्रोग्राम लिखने का काम सौंपा गया है, जो एक मालिकाना डॉस ऑपरेटिंग सिस्टम चलाता है जो कुछ प्रतिबंधों के बावजूद 16-बिट एमएस डॉस के लिए संकलित निष्पादन योग्य चला सकता है। मैं डिजिटल मंगल सी/सी ++ कंपाइलर का उपयोग कर रहा हूं, जो बहुत अच्छी तरह से काम कर रहा है।सी में इनलाइन रूपों के इन दो रूपों के बीच क्या अंतर है?

कुछ चीजों के लिए मैं मानक सी पुस्तकालयों का उपयोग कर सकता हूं, लेकिन यूनिट की स्क्रीन पर ड्राइंग जैसी अन्य चीजों को असेंबली कोड की आवश्यकता होती है। डिवाइस के दस्तावेज़ीकरण में दिए गए असेंबली उदाहरण सी/सी ++ में इनलाइन असेंबली कोड का उपयोग करने के लिए सिखाए जाने से अलग हैं। संदर्भ के लिए, नीचे दिए गए उदाहरणों में BYTE टाइप unsigned char है। उदाहरण के कोड की

नमूना मैं दिया गया था:

#include <dos.h> 

/* Set the state of a pixel */ 
void LCD_setpixel(BYTE x, BYTE y, BYTE status) { 
    if(status > 1 || x > 63 || y > 127) { 
    /* out of range, return */ 
    return; 
    } 
    /* good data, set the pixel */ 
    union REGS regs; 
    regs.h.ah = 0x41; 
    regs.h.al = status; 
    regs.h.dh = x; 
    regs.h.dl = y; 
    int86(0x10, &regs, &regs); 
} 

कैसे मैं हमेशा इनलाइन विधानसभा का उपयोग करने के लिए सिखाया गया था:

/* Set the state of a pixel */ 
void LCD_setpixel(BYTE x, BYTE y, BYTE status) { 
    if(status > 1 || x > 63 || y > 127) { 
    /* out of range, return */ 
    return; 
    } 
    /* good data, set the pixel */ 
    asm { 
    mov AH, 41H 
    mov AL, status 
    mov DH, x 
    mov DL, y 
    int 10H 
    } 
} 

दोनों रूपों काम करने के लिए लगता है, मैं एक समस्या का सामना करना पड़ा नहीं किया है अभी तक दृष्टिकोण के साथ। क्या डॉस प्रोग्रामिंग के लिए एक फॉर्म दूसरे से बेहतर माना जाता है? क्या int86 फ़ंक्शन मेरे लिए कुछ संभालता है कि मैं अपने उदाहरण को अपने दूसरे असेंबली कोड में दूसरे उदाहरण में नहीं रख रहा हूं?

किसी भी मदद के लिए अग्रिम धन्यवाद।

+0

शीर्षक भ्रामक/गलत है। पहले संस्करण में कोई इनलाइन एएसएम नहीं है, सिस्टम कॉल के आस-पास एक फंक्शन-कॉल रैपर है। (या एक कंपाइलर 'int86()' को आंतरिक के रूप में कार्यान्वित कर सकता है और दाएं एएसएम को रेखांकित कर सकता है)। –

उत्तर

9

जब आप int86 फ़ंक्शन कॉल का उपयोग करते हैं, तो यह एक सी रनटाइम लाइब्रेरी कॉल है जो रजिस्टरों को सेट करता है और एक डॉस int त्रुटि फ़ंक्शन जारी करता है। दोनों विधियां वास्तव में एक अपवाद के साथ समान होती हैं, जब आप इनलाइन असेंबलर का उपयोग करते हैं, तो संकलित और लिंक किए जाने पर कोड वास्तव में ऑब्जेक्ट कोड में एम्बेड किया जाता है।

इनलाइन असेंबली को तेज़ी से माना जाएगा क्योंकि आपके पास सी रनटाइम लाइब्रेरी को कॉल करने में ओवरहेड नहीं है जो आपके लिए डॉस इंटरप्ट का आह्वान करता है। इनलाइन असेंबली का उपयोग करते समय पर्याप्त स्टैक स्पेस सुनिश्चित करने के लिए ऑनस आप पर है, जबकि सी रनटाइम लाइब्रेरी int86 फ़ंक्शन का आह्वान करने से पहले रजिस्टरों को सेट करते समय स्टैक स्पेस आवंटित करने का ख्याल रखती है।

int86 डॉस इंटरप्ट्स को आमंत्रित करना आसान बनाने का एक तरीका है। यह कंपेलरों के पुराने बोर्लैंड टर्बो सी सूट और माइक्रोसॉफ्ट पर बेहद लोकप्रिय था, मैं Win 3.1 से पहले पुराने कंपाइलर्स के बारे में बात कर रहा हूं।

बाधा 0x10 है, जो वीडियो आउटपुट के लिए जिम्मेदार है, अगर मैं सही ढंग से याद है, समय की बात हो रही है, कुछ BIOS के नष्ट bp रजिस्टर और वैकल्पिक हल यह करने के लिए किया गया था:

__asm{ 
    push bp; 
} 
/* set up the registers */ 
int86(0x10, &regs, &regs); 
__asm{ 
    pop bp; 
} 

आप कर सकते हैं राल्फ ब्राउन की इंटरप्ट सूची here पर व्यापक BIOS फ़ंक्शंस का पता लगाएं। इसके अलावा हेल्पपीसी v2.1 भी मदद कर सकता है, here मिला।

+0

मुझे लगता है कि मेरे पास कॉलेज में राल्फ ब्राउन की इंटरप्ट सूची की प्रतिलिपि थी, अब मैं इसके बारे में सोचता हूं, और मुझे नहीं पता कि मैंने इसके साथ क्या किया। ऐसा लगता है कि मैं इस भयानक संसाधन को भूल गया था, धन्यवाद! यह बहुत उपयोगी है। राल्फ ब्राउन की इंटरप्ट सूची और हेल्पपीसी –

+0

+1 मुझे संदेह है कि मैं ऐसा कुछ नहीं कर रहा था जिसे मुझे एएसएम ब्लॉक में करने की आवश्यकता थी। धन्यवाद। –

0

इनलाइन विधानसभा नहीं है यही कारण है, यह, सी बहुत निम्न स्तर सी है एक समारोह का उपयोग कर बाधा पैदा करने के लिए, लेकिन अभी भी सी

This page DJGPP संकलक के लिए कुछ प्रलेखन (है, तुम्हारा अलग तरह से काम कर सकते हैं), रजिस्टरों का प्रतिनिधित्व करने के लिए प्रयुक्त संरचना सहित। यह भी नोट:

ध्यान दें कि, के विपरीत __dpmi_int समारोह, अनुरोध करता है कि int86 के माध्यम से जाने के लिए और समान कार्य विशेष रूप से कार्रवाई की जाती है संरक्षित मोड कार्यक्रमों से वास्तविक-मोड बीच में आता है लागू करने के लिए उन्हें उपयुक्त बनाने के लिए । उदाहरण के लिए, यदि कोई विशेष दिनचर्या बीएक्स में एक सूचक लेता है, int86 आपको ईबीएक्स में एक (संरक्षित-मोड) पॉइंटर डालने की अपेक्षा करता है। इसलिए, int86 प्रत्येक इंटरप्ट और फ़ंक्शन के लिए विशिष्ट समर्थन होना चाहिए और आप इस तरीके से इनकार करते हैं। वर्तमान में, यह सभी उपलब्ध बीच में आता है और कार्यों का केवल एक सबसेट का समर्थन करता है [...]

+0

यह डीजेजीपीपी सी कंपाइलर के लिए सच है, क्योंकि int86 एक मानक फ़ंक्शन नहीं है, यह नहीं दिया जाता है कि डिजिटल मंगल कंपाइलर उसी तरह काम करता है, इसमें – Alon

1

प्रथम रूप अधिक पठनीय जो भी कुछ ;-)

के लिए मायने रखता है है अगर आप अगर जानना चाहते हैं int86 आपकी पीठ के पीछे कुछ कर रहा है, बस अपने प्रोग्राम को संकलित करें और जेनरेट किए गए असेंबली कोड की जांच करें

+0

"पहला फॉर्म अधिक पठनीय" हो सकता है। यह है? –

+0

मुझे लगता है कि कौन सा रूप दूसरे की तुलना में अधिक "पठनीय" है, व्यक्तिगत राय का विषय है, क्योंकि व्यक्तिगत रूप से मुझे दूसरा और पठनीय लगता है, लेकिन दोनों समझ में आते हैं। संकलित कोड को विच्छेदन करना आखिरी उपाय का होगा, अगर किसी के पास मेरे पास जवाब नहीं था तो मैं निश्चित रूप से उस मार्ग पर जाऊंगा। –

+0

पहला फॉर्म कंपाइलर्स द्वारा अधिक पठनीय है जो इनलाइन असेंबली के लिए एक अलग प्रारूप का उपयोग करता है। लेकिन आप अनावश्यक फ़ंक्शन कॉल के ऊपरी हिस्से के बारे में चिंता कर सकते हैं, साथ ही 'REGS' यूनियन के तत्वों को संबोधित करते हुए, संभवतः 'int86' सभी रजिस्टरों की प्रतिलिपि बना रहे हैं (जो यूनियन में परिभाषित हैं, न केवल आपके द्वारा उपयोग किए जाने वाले सभी) स्मृति, फिर उन्हें फिर से वापस कॉपी करें (जिसे आप छोड़ दें)। –

1

int86 को कॉल करके, आपका कोड सी में रहता है। किसी भी तरह से, यह सिस्टम इंटरप्ट करके पिक्सेल लिख रहा है।

यदि आपके पास बहुत पिक्सेल लिखने के लिए है, और आप गति समस्याओं को गंभीरता से मारना शुरू करते हैं, तो पिक्सेल मेमोरी पर सीधे लिखने के लिए एक और प्रत्यक्ष (और बहुत कम सुरक्षित लेकिन संभवतः सार्थक) तरीका हो सकता है।

+0

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

+0

@ हेदर: हाँ, मैंने आपकी मशीन देखी, और स्क्रीन मोनोक्रोम और छोटी है, इसलिए मुझे संदेह है कि ग्राफिक्स एक बाधा से अधिक होगा। –

1

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

+0

का उल्लेख करने के लिए –

1

आपको इनलाइन असेंबली सेक्शन के बाद रजिस्टर मानों को पुनर्स्थापित करने के लिए जिम्मेदार कौन है, यह जानने के लिए आपको कंपाइलर्स मैन्युअल जांचना चाहिए। चूंकि आपके चर रजिस्टरों को असाइन किए जाते हैं, इसलिए मानों के अनपेक्षित परिवर्तनों से हार्ड-टू-बग बग हो सकता है। int86 (0x10, & regs, & regs); रजिस्टरों को बचाता है और सॉफ़्टवेयर-बाधा को निष्पादित करने के बाद उन्हें पुनर्स्थापित करता है।

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

+0

मैं int86 के बारे में सहमत हूं - मुझे लगता है कि जब तक गति वास्तविक समस्या नहीं बन जाती है, तब तक मैं इस दृष्टिकोण का सुरक्षित उपयोग करूंगा, धन्यवाद :) –

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