मैं उबंटू के तहत नस्ल का उपयोग कर रहा हूं। वैसे मुझे उपयोगकर्ता के कीबोर्ड से एकल इनपुट कैरेक्टर प्राप्त करने की आवश्यकता है (जैसे कि जब कोई प्रोग्राम आपको y/n के लिए पूछता है?) ताकि कुंजी दबाए और एंटर दबाए बिना मुझे दर्ज किए गए चरित्र को पढ़ने की आवश्यकता हो। मैंने इसे बहुत गुमराह किया लेकिन जो कुछ मैंने पाया वह किसी भी तरह से इस लाइन से संबंधित था (int 21h
) जिसके परिणामस्वरूप "सेगमेंटेशन फॉल्ट" होता है। कृपया मुझे यह समझने में सहायता करें कि एकल चरित्र कैसे प्राप्त करें या इस सेगमेंटेशन गलती को कैसे खत्म किया जाए।उबंटू के तहत नासम (असेंबली) का उपयोग करके कीबोर्ड से एकल वर्ण इनपुट कैसे पढ़ूं?
उत्तर
यह असेंबली से किया जा सकता है, लेकिन यह आसान नहीं है। आप int 21h का उपयोग नहीं कर सकते हैं, यह एक डॉस सिस्टम कॉल है और यह लिनक्स के तहत उपलब्ध नहीं है।
यूनिक्स जैसे ऑपरेटिंग सिस्टम (जैसे लिनक्स) के तहत टर्मिनल से पात्र प्राप्त करने के लिए, आप STDIN (फ़ाइल संख्या 0) से पढ़ते हैं। आम तौर पर, जब तक उपयोगकर्ता प्रेस दर्ज नहीं करता है तब तक पढ़ा गया सिस्टम कॉल अवरुद्ध हो जाएगा। इसे कैनोलिक मोड कहा जाता है। उपयोगकर्ता को एंटर दबाए रखने के इंतजार किए बिना एक सिंगल कैरेक्टर को पढ़ने के लिए, आपको पहले कैननिकल मोड को अक्षम करना होगा। बेशक, यदि आप बाद में लाइन इनपुट चाहते हैं, और आपके प्रोग्राम से बाहर निकलने से पहले आपको इसे फिर से सक्षम करना होगा।
लिनक्स पर प्रामाणिक मोड अक्षम करने के लिए, आप STDIN को एक IOCTL (आईओ नियंत्रण) भेजने के लिए, ioctl syscall का उपयोग कर। मुझे लगता है कि आप जानते हैं कि कैसे लिनक्स सिस्टम को असेंबलर से कॉल करना है।
ioctl syscall में तीन पैरामीटर हैं। पहली बार आदेश (एसटीडीआईएन) को भेजने के लिए फ़ाइल है, दूसरा आईओसीटीएल नंबर है, और तीसरा आम तौर पर डेटा संरचना के लिए एक सूचक है। सफलता पर ioctl 0, या असफल पर एक नकारात्मक त्रुटि कोड देता है।
पहले IOCTL आप की जरूरत TCGETS (संख्या 0x5401) जो एक termios संरचना में वर्तमान टर्मिनल पैरामीटर हो जाता है। तीसरा पैरामीटर टर्मियो संरचना के लिए एक सूचक है। कर्नेल स्रोत से, termios संरचना के रूप में परिभाषित किया गया है:
struct termios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
};
जहां tcflag_t 32 बिट्स है, cc_t एक बाइट लंबा है, और एनसीसीएस वर्तमान में देखें तो आप आसानी से कैसे परिभाषित कर सकते हैं के लिए एनएएसएम मैनुअल 19. के रूप में परिभाषित किया गया है और इस तरह की संरचनाओं के लिए आरक्षित जगह।
तो एक बार जब आपको वर्तमान टर्मियो मिल जाए, तो आपको कैनोलिक ध्वज को साफ़ करने की आवश्यकता है। यह ध्वज c_lflag फ़ील्ड में है, मास्क ICANON (0x00000002) के साथ। इसे साफ़ करने के लिए, c_lflag गणना करें (और ICANON नहीं)। और परिणाम को वापस c_lflag फ़ील्ड में संग्रहीत करें।
अब आपको टर्मियो संरचना में अपने परिवर्तनों के कर्नेल को सूचित करने की आवश्यकता है। टीसीएसईटीएस (संख्या 0x5402) ioctl का उपयोग करें, तीसरे पैरामीटर के साथ आपके टर्मियोस संरचना का पता सेट करें।
यदि सब ठीक हो जाए, तो टर्मिनल अब गैर-कैनोलिक मोड में है। आप कैनोलिक फ्लैग को सेट करके कैननिकल मोड को पुनर्स्थापित कर सकते हैं (आईसीएएनओएन के साथ ऑरिंग c_lflag द्वारा) और टीसीएसईटीएस ioctl को दोबारा कॉल कर सकते हैं।
से बाहर निकलने से पहले हमेशा कैननिकल मोड को पुनर्स्थापित करें जैसा कि मैंने कहा, यह आसान नहीं है।
आसान तरीका: एक पाठ-मोड कार्यक्रम के लिए, libncurses कीबोर्ड का उपयोग करने के लिए; एक ग्राफिकल प्रोग्राम के लिए, Gtk+ का उपयोग करें।
कठिन तरीका: टेक्स्ट-मोड प्रोग्राम मानते हुए, आपको कर्नेल को यह बताना होगा कि आप सिंगल-कैरेक्टर इनपुट चाहते हैं, और फिर आपको पूरी तरह से बहीखाता और डिकोडिंग करना होगा। यह वास्तव में जटिल है। अच्छे पुराने डॉस getch()
दिनचर्या के बराबर नहीं है। आप प्रारंभ कर सकते हैं कि यह कैसे करें: Terminal I/O। ग्राफिकल कार्यक्रम और भी जटिल हैं; इसके लिए निम्नतम स्तर API Xlib है।
किसी भी तरह से, आप जो कुछ भी असेंबली में पागल कोडिंग करने जा रहे हैं; इसके बजाय सी का उपयोग करें।
मैं इस हाल ही में करने के लिए की जरूरत है, और कैलम के excellent answer से प्रेरित, मैं निम्नलिखित लिखा है:
termios: times 36 db 0
stdin: equ 0
ICANON: equ 1<<1
ECHO: equ 1<<3
canonical_off:
call read_stdin_termios
; clear canonical bit in local mode flags
push rax
mov eax, ICANON
not eax
and [termios+12], eax
pop rax
call write_stdin_termios
ret
echo_off:
call read_stdin_termios
; clear echo bit in local mode flags
push rax
mov eax, ECHO
not eax
and [termios+12], eax
pop rax
call write_stdin_termios
ret
canonical_on:
call read_stdin_termios
; set canonical bit in local mode flags
or dword [termios+12], ICANON
call write_stdin_termios
ret
echo_on:
call read_stdin_termios
; set echo bit in local mode flags
or dword [termios+12], ECHO
call write_stdin_termios
ret
read_stdin_termios:
push rax
push rbx
push rcx
push rdx
mov eax, 36h
mov ebx, stdin
mov ecx, 5401h
mov edx, termios
int 80h
pop rdx
pop rcx
pop rbx
pop rax
ret
write_stdin_termios:
push rax
push rbx
push rcx
push rdx
mov eax, 36h
mov ebx, stdin
mov ecx, 5402h
mov edx, termios
int 80h
pop rdx
pop rcx
pop rbx
pop rax
ret
फिर आप कर सकते हैं:
call canonical_off
आप टेक्स्ट की पंक्ति में पढ़ रहे हैं , आप शायद यह भी करना चाहते हैं:
call echo_off
ताकि प्रत्येक चरित्र टाइप किए जाने के रूप में प्रतिबिंबित न हो।
ऐसा करने के बेहतर तरीके हो सकते हैं, लेकिन यह 64-बिट फेडोरा स्थापना पर मेरे लिए काम करता है।
अधिक जानकारी termios(3)
, या termbits.h
source में मैन पेज में मिल सकती है।
- 1. मैं Winform पर कीबोर्ड इनपुट कैसे पढ़ूं?
- 2. विंडोज असेंबली में नासम का उपयोग कर हैलो दुनिया
- 3. नासम
- 4. कीबोर्ड "इनपुट" से इनपुट को संभालने का सबसे अच्छा तरीका
- 5. मैं WPF में उपयोगकर्ता से कस्टम कीबोर्ड शॉर्टकट कैसे पढ़ूं?
- 6. पॉइंटर्स का उपयोग करके मैं संरचना में मूल्य कैसे पढ़ूं?
- 7. एकाधिक परियोजनाओं से एकल असेंबली
- 8. एकल माउस और कीबोर्ड
- 9. मैं जावा में स्वरूपित इनपुट कैसे पढ़ूं?
- 10. मैं जावा में इनपुट कैरेक्टर-बाय-कैरेक्टर कैसे पढ़ूं?
- 11. प्रयुक्त इनपुट के बाद कीबोर्ड कैसे दिखाएं
- 12. मैंस्पिस्प्लिब का उपयोग करके यूनिकोड वर्ण कैसे पोस्ट करूं?
- 13. पर्ल इनपुट और कीबोर्ड इनपुट के लिए पर्ल को विभिन्न हैंडल का उपयोग कैसे करें?
- 14. मैं गूंज का उपयोग करके गैर-ASCII वर्ण कैसे लिखूं?
- 15. cmd में विशेष वर्ण कैसे इनपुट करें?
- 16. LINQ से XML का उपयोग करके एन्क्रिप्टेड XML फ़ाइल को मैं कैसे पढ़ूं/लिखूं?
- 17. ओपनएक्सएमएल प्रारूप एसडीके का उपयोग करके मैं स्प्रेडशीट से डेटा कैसे पढ़ूं?
- 18. एकल वर्ण मिलान के लिए वैकल्पिक या वर्ण वर्ग का उपयोग करना?
- 19. प्रभावी कीबोर्ड इनपुट हैंडलिंग
- 20. इनपुट (माउस + कीबोर्ड)
- 21. मैं उबंटू के तहत जीवीआईएम कैसे संकलित कर सकता हूं?
- 22. /dev/इनपुट कीबोर्ड प्रारूप
- 23. शीतल इनपुट कीबोर्ड एंड्रॉयड
- 24. कीबोर्ड इनपुट आईओएस
- 25. उबंटू लिनक्स के तहत सी ++ को संकलित कैसे करें?
- 26. ग्रहण: केवल कीबोर्ड (कीबोर्ड-शॉर्टकट) का उपयोग करके त्रुटि में कैसे जाना है?
- 27. उबंटू के तहत Xilinx ISE वेब पैक कैसे लॉन्च करें?
- 28. जावा स्ट्रीम कीबोर्ड इनपुट
- 29. ऑब्जेक्टकंटेंट मैनेजर का उपयोग करके मैं नोड के तहत नोड कैसे जोड़ सकता हूं?
- 30. कंसोल ऐप में जावा कीबोर्ड इनपुट पार्सिंग
जबकि आपने जो भी कहा है, वह सी के लिए सही है, यदि ओपी असेंबली सीखने की कोशिश कर रहा है तो यह वास्तव में एक प्रासंगिक उत्तर नहीं है। –
ऐसा इसलिए है क्योंकि ओपी * असेंबली भाषा * में प्रोग्रामिंग नहीं होनी चाहिए। असेंबली भाषा में कुछ भी हाथ कोड करने का एकमात्र अच्छा कारण यह है कि यह एक प्रदर्शन-महत्वपूर्ण कम्प्यूटेशनल सबराउटिन है, या एक ऑपरेटिंग सिस्टम कर्नेल के बहुत कम निम्न स्तर के टुकड़ों में से एक है जिसे * किसी भी अन्य तरीके से कोड नहीं किया जा सकता है। उपयोगकर्ता बातचीत योग्य नहीं है। ओपी क्या कर रहा है वह यूनिक्स के तहत भी एक अच्छा * सीखने का अभ्यास नहीं है। – zwol
ऐसा कहकर, ओपी को असेंबली भाषा लिखने से रोकना नहीं है जो libncurses को कॉल करता है, हालांकि यह मुझे समय और गहनता की गड़बड़ी की तरह लगता है (लेकिन यह यूनिक्स टर्मिनल I की असेंबली भाषा के रूप में उतना ही बुरा नहीं होगा।/हाथ से)। – zwol