2011-05-09 18 views

उत्तर

9

सिस्कोल को कर्नेल से सेवा का अनुरोध करने के लिए उपयोग किया जाता है। एमआईपीएस के लिए, सेवा संख्या/कोड $ v0 में पारित किया जाना चाहिए और कुछ अन्य नामित रजिस्टरों में तर्क पारित किए गए हैं। उदाहरण के लिए, प्रिंट करने के लिए हम कर सकते हैं:

li $v0, 1 
add $a0, $t0, $zero 
syscall 

इस मामले में, 1 प्रिंट पूर्णांक के लिए सेवा कोड है। दूसरा निर्देश प्रभावी रूप से एक प्रतिलिपि $ t0 से $ a0 तक करता है जो नामित रजिस्टर होता है जहां तर्क होता है (इस मामले में, पूर्णांक मुद्रित करने के लिए)। सेवाओं और संबंधित तर्कों की एक सूची दी गई है: http://courses.missouristate.edu/KenVollmar/Mars/Help/SyscallHelp.html

5

जब आप एमएआरएस या स्पिम जैसे एमुलेटर के संदर्भ से बाहर निकलते हैं तो यह बहुत अधिक स्पष्ट हो जाता है जहां सिस्टम कॉल कुछ कृत्रिम होते हैं। वास्तविक एमआईपीएस मशीन पर, आप इसे एक विशिष्ट फ़ंक्शन का आह्वान करने के लिए कर्नेल को ट्रांसफर नियंत्रण का उपयोग करेंगे।

उदाहरण के लिए, यह एक Linux मशीन के लिए MIPS 32-बिट विधानसभा में एक बुनियादी नमस्ते दुनिया कार्यक्रम है

(मैं 95% यकीन है कि यह स्थापित करते हैं, नहीं है कि यह इस प्रश्न के लिए बहुत मायने रखती है एक mipsel पर था हूँ)
# CS341L Fall 2008 
# Lab Exercise #1 
# Matthew J. Barrick <[email protected]> 

#include <asm/regdef.h> 
#include <sys/syscall.h> 

.data 
    hello: .asciz "Hello World\n" 
    length: .word 12 
.text 
    .globl main 
    .ent main 
main: 
    li a0, 1 
    la a1, hello 
    lw a2, length 
    li v0, SYS_write 
    syscall 
    move v0, zero 
    jr ra 
    .end main 

यह सी कोड के बहुत करीब से मेल खाता है (यदि आपको एमआईपीएस असेंबली के बाद परेशानी है)।

#include <stdio.h> 

int main(int argc, char** argv) { 
    char* hello = "Hello World\n"; 
    write(STDOUT_FILENO,hello, 12); 
    return 0; 
} 

सबसे पहले ध्यान दें कि हेडर रजिस्टरों प्रतीकात्मक नाम (ASM/regdef.h) और इसमें एक शीर्ष कि सिस्टम कॉल (sys/syscall.h) के लिए प्रतीकात्मक नाम में खींच लेंगे देने के लिए शामिल किए गए हैं तो हम डॉन ' संख्या के अनुसार syscalls का उल्लेख नहीं है। यहां एक सिस्टम कॉल करने के लिए सम्मेलन एक समारोह को कॉल करने के समान ही हैं, तर्क के साथ # रजिस्टर लोड करें, फिर हम उस सिस्टम कॉल को लोड करते हैं जिसे हम $ v0 में चाहते हैं और syscall का आह्वान करते हैं। SYS_write लिनक्स/यूनिक्स (1 मानक आउट होने के लिए) के लिए मूल लेखन (2) फ़ंक्शन से मेल खाता है।

ssize_t write(int fd, const void *buf, size_t count); 

तो हम फ़ाइल हैंडल 1 (stdout) में लिखने के लिए कर्नेल कह रहे हैं, स्ट्रिंग हैलो, लंबाई बाइट्स का उपयोग कर। लिनक्स पर आप सभी अलग-अलग सिस्कोल के लिए सिस्कोल (2) देख सकते हैं, लेकिन वे कर्नेल द्वारा प्रदान किए जाने वाले मूल कार्यों से बहुत अधिक मेल खाते हैं और वह (जी) libc या तो सी/सी ++ प्रोग्राम के लिए लपेटता है या बनाता है।

लिनक्स (और अधिकांश यूनिक्स-पसंद 4BSD मार्ग पर वापस जा रहे हैं) में फ़ंक्शन सिस्कल (2) है जो प्रभावी रूप से एक ही चीज़ है।

एक बार जब आप अधिक जटिल चीजें करना शुरू कर देते हैं तो आप या तो अपने आप को आसान कार्यों में आमंत्रित करने के लिए सिस्कोल को लपेट लेंगे, या बेहतर अभी तक संबंधित libc संस्करणों को कॉल करना (आश्चर्यजनक रूप से आसान करना, लेकिन एक और चर्चा)।