असेंबली कोड में "int 0x80" का क्या अर्थ है?


90

क्या कोई समझा सकता है कि निम्नलिखित विधानसभा कोड क्या करता है?

 int 0x80  

जवाबों:


70

यह वेक्टर 0x80 को बाधित करने के लिए नियंत्रण पास करता है

Http://en.wikipedia.org/wiki/Interrupt_vector देखें

लिनक्स पर, पर एक नजर है इस : इसे संभाल करने के लिए इस्तेमाल किया गया था system_call। बेशक दूसरे OS पर इसका मतलब कुछ अलग हो सकता है।


5
छोटी लंबी कहानी द्वारा यह निर्देश दिया जाता है कि निर्देश के लिए DO IT पहले था।
युदा प्रवीरा

2
@YudaPrawira: आपको पहले के निर्देशों के बारे में सोचना चाहिए कि रजिस्टरों में args की स्थापना, और कर्नेल में int 0x80एक विशेष प्रकार के callफ़ंक्शन के रूप में (द्वारा चयनित eax)।
पीटर कॉर्डेस

आपने "WAS का उपयोग क्यों किया?" क्या यह अब उपयोग नहीं किया जाता है?
लीगा

130

intका मतलब है रुकावट, और संख्या 0x80में बाधा संख्या है। एक व्यवधान कार्यक्रम के प्रवाह को पूर्णता में स्थानांतरित करता है जो उस रुकावट को संभाल रहा है, जो 0x80इस मामले में बाधित है। लिनक्स में, 0x80बाधा हैंडलर कर्नेल है, और कर्नेल को अन्य कार्यक्रमों द्वारा सिस्टम कॉल करने के लिए उपयोग किया जाता है।

कर्नेल को सूचित किया जाता है कि रजिस्टर में मूल्य %eax(एटी एंड टी सिंटैक्स और इंटेल सिंटैक्स में ईएक्सएक्स) की जांच करके कौन सा सिस्टम कॉल करना चाहता है । प्रत्येक प्रणाली कॉल में अन्य रजिस्टरों के उपयोग के बारे में अलग-अलग आवश्यकताएं हैं। उदाहरण के लिए, के एक मूल्य 1में %eaxकी एक प्रणाली कॉल का मतलब है exit(), और में मूल्य %ebxके लिए स्थिति कोड का मान रखती है exit()


47

ध्यान रखें कि 0x80= 80h=128

आप यहां देख सकते हैं कि INTकई निर्देशों में से एक है (वास्तव में असेंबली लैंग्वेज प्रतिनिधित्व (या मुझे इसे 'मेनेमोनिक' कहना चाहिए) जो कि x86 इंस्ट्रक्शन सेट में मौजूद है। आप इस निर्देश के बारे में अधिक जानकारी इंटेल के स्वयं के मैनुअल में पा सकते हैं

पीडीएफ से सारांशित करने के लिए:

INT n / INTO / INT 3-बाधित प्रक्रिया को बुलावा

INT n निर्देश गंतव्य ऑपरेंड के साथ निर्दिष्ट बाधा या अपवाद हैंडलर को कॉल उत्पन्न करता है। गंतव्य ऑपरेंड एक वेक्टर को 0 से 255 तक निर्दिष्ट करता है, जिसे 8-बिट अहस्ताक्षरित मध्यवर्ती मान के रूप में एन्कोड किया गया है। INT n निर्देश एक सॉफ्टवेयर-जनरेट किए गए कॉल को एक हैंडलर को निष्पादित करने के लिए सामान्य महामारी है।

आप देख सकते हैं 0x80 है गंतव्य संकार्य अपने प्रश्न में। इस बिंदु पर सीपीयू जानता है कि उसे कर्नेल में रहने वाले कुछ कोड को निष्पादित करना चाहिए, लेकिन क्या कोड? यह लिनक्स में इंटरप्ट वेक्टर द्वारा निर्धारित किया जाता है।

सबसे उपयोगी डॉस सॉफ्टवेयर में से एक इंटरप्ट 0x21 था। रजिस्टरों (ज्यादातर आह और अल) में विभिन्न मापदंडों के साथ इसे कॉल करके आप विभिन्न IO संचालन, स्ट्रिंग आउटपुट और अधिक का उपयोग कर सकते हैं।

अधिकांश यूनिक्स सिस्टम और डेरिवेटिव्स सॉफ्टवेयर इंटरप्ट का उपयोग नहीं करते हैं, 0x80 के बीच के अंतर के साथ, सिस्टम कॉल करने के लिए उपयोग किया जाता है। यह प्रोसेसर के EAX रजिस्टर में कर्नेल फ़ंक्शन के अनुरूप 32-बिट मान दर्ज करके और फिर INT 08080 निष्पादित करके पूरा किया जाता है ।

कृपया इस पर एक नज़र डालें कि इंटरप्ट हैंडलर टेबल में अन्य उपलब्ध मान कहाँ दिखाए गए हैं:

यहां छवि विवरण दर्ज करें

जैसा कि आप देख सकते हैं कि टेबल एक सिस्टम कॉल को निष्पादित करने के लिए सीपीयू को इंगित करता है। आप यहां लिनक्स सिस्टम कॉल टेबल पा सकते हैं ।

तो मान 0x1 को EAX रजिस्टर में ले जाकर और अपने प्रोग्राम में INT 0x80 पर कॉल करके, आप प्रक्रिया को कर्नेल में कोड को निष्पादित कर सकते हैं जो वर्तमान चल रही प्रक्रिया (लिनक्स, x86 इंटेल सीपीयू पर) को रोक देगा (बाहर निकल जाएगा)।

एक हार्डवेयर व्यवधान को सॉफ़्टवेयर रुकावट के साथ भ्रमित नहीं होना चाहिए। यहाँ इस संबंध में एक बहुत अच्छा जवाब है।

यह भी अच्छा स्रोत है।


4
लिनक्स सिस्टम कॉल टेबल लिंक टूट गया है = \
मिगेल एंजेलो

1
अधिकांश यूनिक्स सिस्टम और डेरिवेटिव सॉफ्टवेयर इंटरप्ट का उपयोग नहीं करते हैं (int 0x80 को छोड़कर) इसे लगाने का एक अजीब तरीका लगता है। int 0x80I386 लिनक्स सिस्टम कॉल ABI अत्यंत डॉस के समान है int 0x21ABI। एक रजिस्टर में एक कॉल नंबर डालें (डॉस के लिए एएच, लिनक्स के लिए ईएक्सएक्स), और अन्य रजिस्टरों में अन्य आर्ग्स, फिर एक सॉफ्टवेयर-इंटरफेयर इंस्ट्रक्शन चलाएं। मुख्य अंतर यह है कि सिस्टम कॉल आपको क्या करने देता है (हार्डवेयर को सीधे डॉस में नहीं बल्कि लिनक्स में एक्सेस करें), न कि आप उन्हें कैसे इनवाइट करते हैं।
पीटर कॉर्डेस

यहाँ एक गैर-टूटी हुई syscall तालिका लिंक है। syscalls.kernelgrok.com शीर्ष पर सभी कॉल दिखाने के लिए इसे विस्तृत करें।
ollien

Linux 64bits उपयोग करते समय, आप सिस्टम कॉल पर उपलब्ध देख सकते हैं/usr/include/x86_64-linux-gnu/asm/unistd_64.h
टन

13

न्यूनतम रननीय लिनक्स सिस्टम कॉल उदाहरण

लिनक्स 0x80इस तरह के लिए बाधा हैंडलर सेट करता है कि यह सिस्टम कॉल को लागू करता है, कर्नेल के साथ संवाद करने के लिए उपयोगकर्तालैंड प्रोग्राम का एक तरीका है।

.data
    s:
        .ascii "hello world\n"
        len = . - s
.text
    .global _start
    _start:

        movl $4, %eax   /* write system call number */
        movl $1, %ebx   /* stdout */
        movl $s, %ecx   /* the data to print */
        movl $len, %edx /* length of the buffer */
        int $0x80

        movl $1, %eax   /* exit system call number */
        movl $0, %ebx   /* exit status */
        int $0x80

इसके साथ संकलित करें और चलाएं:

as -o main.o main.S
ld -o main.out main.o
./main.out

परिणाम: कार्यक्रम प्रिंट करने के लिए:

hello world

और सफाई से बाहर निकलता है।

आप अपने स्वयं के व्यवधान संचालकों को उपयोगकर्ताभूमि से सीधे सेट नहीं कर सकते क्योंकि आपके पास केवल रिंग 3 है और लिनक्स आपको ऐसा करने से रोकता है

गिटहब ऊपर । उबंटू 16.04 पर परीक्षण किया गया।

बेहतर विकल्प

int 0x80सिस्टम कॉल करने के लिए बेहतर विकल्पों से अलग हो गया है: पहले sysenter, फिर VDSO।

x86_64 में एक नया syscallनिर्देश है

यह भी देखें: बेहतर क्या है "int 0x80" या "syscall"?

न्यूनतम 16-बिट उदाहरण

पहले सीखें कि कैसे एक न्यूनतम बूटलोडर ओएस बनाया जाए और इसे QEMU और असली हार्डवेयर पर चलाया जाए जैसा कि मैंने यहां बताया है: https://stackoverflow.com/a/32483545/895245

अब आप 16-बिट वास्तविक मोड में चला सकते हैं:

    movw $handler0, 0x00
    mov %cs, 0x02
    movw $handler1, 0x04
    mov %cs, 0x06
    int $0
    int $1
    hlt
handler0:
    /* Do 0. */
    iret
handler1:
    /* Do 1. */
    iret

यह क्रम में करना होगा:

  • Do 0.
  • Do 1.
  • hlt: अमल करना बंद करो

ध्यान दें कि प्रोसेसर पते पर पहले हैंडलर के लिए कैसा दिखता है 0, और दूसरा एक 4: जो हैंडलर की एक तालिका है जिसे आईवीटी कहा जाता है , और प्रत्येक प्रविष्टि में 4 बाइट्स हैं।

न्यूनतम उदाहरण जो हैंडलर को दृश्यमान बनाने के लिए कुछ IO करता है

न्यूनतम संरक्षित मोड उदाहरण है

आधुनिक ऑपरेटिंग सिस्टम तथाकथित संरक्षित मोड में चलते हैं।

इस मोड में हैंडलिंग के अधिक विकल्प हैं, इसलिए यह अधिक जटिल है, लेकिन भावना समान है।

प्रमुख कदम LGDT और LIDT निर्देशों का उपयोग कर रहा है, जो हैंडलर का वर्णन करने वाली इन-मेमोरी डेटा संरचना (इंटरप्ट डिस्क्रिप्टर टेबल) के पते को इंगित करता है।

न्यूनतम उदाहरण


9

int 0x80 असेंबली लैंग्वेज इंस्ट्रक्शन है जिसका उपयोग लिनक्स में x86 (यानी, इंटेल-कम्पेटिबल) प्रोसेसर पर सिस्टम कॉल को इनवोक करने के लिए किया जाता है।

http://www.linfo.org/int_0x80.html


4

"इंट" निर्देश एक बाधा का कारण बनता है।

एक बाधा क्या है?

सरल उत्तर: एक रुकावट, बस रखा जाता है, एक ऐसी घटना है जो सीपीयू को बाधित करती है, और इसे एक विशिष्ट कार्य चलाने के लिए कहती है।

विस्तृत जवाब :

CPU में मेमोरी में संग्रहीत इंटरप्ट सर्विस रूटिन (या ISRs) की एक तालिका होती है। रियल (16-बिट) मोड में, इस रूप में संग्रहीत किया जाता है IVT , या मैं nterrupt वी Ector टी में सक्षम। IVT आम तौर पर 0x0000:0x0000(भौतिक पते 0x00000) पर स्थित होता है , और यह खंड-ऑफसेट पते की एक श्रृंखला है जो ISRs को इंगित करता है। OS पहले से मौजूद IVT प्रविष्टियों को अपने ISRs से बदल सकता है।

(नोट: आईवीटी का आकार 1024 (0x400) बाइट्स पर तय किया गया है)

संरक्षित (32-बिट) मोड में, CPU एक IDT का उपयोग करता है। IDT एक वैरिएबल-लेंथ स्ट्रक्चर है , जिसमें डिस्क्रिप्टर होते हैं (जिन्हें गेट्स के रूप में जाना जाता है), जो CPU को इंटरप्ट हैंडलर के बारे में बताते हैं। इन विवरणकों की संरचना आईवीटी के सरल सेगमेंट-ऑफ़सेट प्रविष्टियों की तुलना में बहुत अधिक जटिल है; यह रहा:

bytes 0, 1: Lower 16 bits of the ISR's address.
bytes 2, 3: A code segment selector (in the GDT/LDT)
byte 4: Zero.
byte 5: A type field consisting of several bitfields.
    bit 0:  P (Present): 0 for unused interrupts, 1 for used interrupts.*
    bits 1, 2: DPL (Descriptor Privilege Level): The privilege level the descriptor (bytes 2, 3) must have.
    bit 3: S (Storage Segment): Is 0 for interrupt and trap gates. Otherwise, is one. 
    bits 4, 5, 6, 7: GateType:
        0101: 32 bit task gate
        0110: 16-bit interrupt gate
        0111: 16-bit trap gate
        1110: 32-bit interrupt gate
        1111: 32-bit trap gate
 

* IDT परिवर्तनशील आकार का हो सकता है, लेकिन यह अनुक्रमिक होना चाहिए, अर्थात यदि आप अपना IDT 0x00 से 0x50 तक होने की घोषणा करते हैं, तो आपके पास 0x00 से 0x50 तक प्रत्येक व्यवधान होना चाहिए। ओएस आवश्यक रूप से उन सभी का उपयोग नहीं करता है, इसलिए वर्तमान बिट सीपीयू को ठीक से संभालने की अनुमति देता है बाधित ओएस ओएस को संभालने का इरादा नहीं करता है।

जब एक IRQ में (या intकिसी प्रोग्राम से निर्देश के द्वारा एक बाहरी ट्रिगर (जैसे एक हार्डवेयर डिवाइस) द्वारा एक अवरोध उत्पन्न होता है ), CPU EFLAGS, फिर CS, और फिर EIP को धकेलता है। (ये स्वचालित रूप से बहाल हो जाते हैं iret, बाधा वापसी निर्देश।) ओएस आमतौर पर मशीन की स्थिति के बारे में अधिक जानकारी संग्रहीत करता है, बाधा को संभालता है, मशीन की स्थिति को पुनर्स्थापित करता है, और जारी रहता है।

कई * NIX OSes (लिनक्स सहित) में, सिस्टम कॉल आधारित हैं। कार्यक्रम रजिस्टर (EAX, EBX, ECX, EDX, आदि) में सिस्टम कॉल के लिए तर्कों को डालता है, और 0x80 को बाधित करता है। कर्नेल ने पहले से ही 0x80 पर एक बाधा हैंडलर रखने के लिए IDT निर्धारित किया है, जिसे तब कहा जाता है जब इसे 0x80 के बीच अवरोध प्राप्त होता है। कर्नेल फिर तर्कों को पढ़ता है और तदनुसार कर्नेल फ़ंक्शन को आमंत्रित करता है। यह EAX / EBX में रिटर्न स्टोर कर सकता है। सिस्टम कॉल काफी हद तक ने ले ली है sysenterऔर sysexit(या syscallऔर sysretएएमडी पर) निर्देश है, जो अंगूठी 0 में तेजी से प्रवेश के लिए अनुमति देते हैं।

इस रुकावट का एक अलग ओएस में एक अलग अर्थ हो सकता है। इसके प्रलेखन की जाँच अवश्य करें।


मजेदार तथ्य: FreeBSD का i386 सिस्टम कॉल ABI पास उपयोगकर्ता-स्पेस स्टैक पर आर्ग करता है। केवल eaxsyscall नंबर के लिए उपयोग किया जाता है। asm.sourceforge.net/intro/hello.html
पीटर कॉर्ड्स

2

जैसा कि उल्लेख किया गया है, यह वेक्टर 0x80 को बाधित करने के लिए कूदने के लिए नियंत्रण का कारण बनता है। व्यवहार में इसका अर्थ है (कम से कम लिनक्स के तहत) यह है कि एक सिस्टम कॉल को लागू किया जाता है; सटीक सिस्टम कॉल और तर्कों को रजिस्टरों की सामग्री द्वारा परिभाषित किया गया है। उदाहरण के लिए, एग्जिट () '% 0x80' के बाद% eax को 1 पर सेट करके लागू किया जा सकता है।


1

यह सीपीयू को बाधित वेक्टर 0x80 को सक्रिय करने के लिए कहता है, जो कि लिनक्स ओएस पर सिस्टम-कॉल इंटरप्ट है, जिसका उपयोग open()फाइलों, एट सीटेरा जैसे सिस्टम फ़ंक्शन को लागू करने के लिए किया जाता है ।


9
कड़ाई से बोलने पर, यह कर्नेल को नहीं बताता है ... यह सीपीयू को बताता है, जो आईडीटी में हैंडलर को देखता है, जो कुछ कर्नेल कोड के लिए एक पॉइंटर होने का संकेत देता है।
असवीकाऊ

सच। मुझे लगता है कि बेहतर phrasing होगा यह CPU को वेक्टर को सक्रिय करने के लिए कहता है, और वेक्टर (कर्नेल के भाग के रूप में) फ़ंक्शन को आमंत्रित करता है।
अंबर ३०'०

जो ऐसा करने के लिए समाप्त होता है, जो अंत में ऐसा करने से समाप्त होता है, जो तब ऐसा करता है, जो तब भ्रमित हो जाता है । : / अम्बर के पास एक जवाब है जो समझ में आता
है..तो

1

int एक रुकावट के अलावा कुछ भी नहीं है अर्थात प्रोसेसर अपने वर्तमान निष्पादन को रोक कर रखेगा।

0x80 एक सिस्टम कॉल या कर्नेल कॉल के अलावा कुछ भी नहीं है। यानी सिस्टम फ़ंक्शन को निष्पादित किया जाएगा।

विशिष्ट होने के लिए 0x80 rt_sigtimedwait / init_module / restart_sys का प्रतिनिधित्व करता है जो वास्तुकला से वास्तुकला में भिन्न होता है।

अधिक जानकारी के लिए https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md देखें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.