हां, आप VOPs (Virtual Operations) का उपयोग करके सीपीयू रजिस्टरों तक पहुंच सकते हैं। वीओपी में आप असेंबली में भी कोड लिख सकते हैं, इसलिए उस अर्थ में आप जीसीसी विस्तारित असेंबली जैसे वीओपी का उपयोग कर सकते हैं।
तो, यहां एक उदाहरण VOP और इसे निष्पादित करने के लिए संबंधित फ़ंक्शन है। get-cpuid-eax
VOP, इनपुट के रूप में दो अहस्ताक्षरित 32-बिट तर्क प्राप्त करता eax
और ecx
में उन्हें संग्रहीत करता है, cpuid
अनुदेश निष्पादित करता है, और cpuid
get-cpuid-eax
को समारोह है कि VOP कहा जाता है के बाद eax
रजिस्टर के मान देता है। get-cpuid-eax
फ़ंक्शन फिर *result*
में मान संग्रहीत करता है। आप (format t "~a" *result*)
के साथ आसानी से मूल्य प्रिंट कर सकते हैं।
नोट: कुछ समस्या है (एसबीसीएल में या मेरे कोड में बग?) जो इस कोड को हमेशा समस्याओं के बिना निष्पादित नहीं करता है। रीकंपलिंग और पुनः लोडिंग आमतौर पर मदद करता है। मैंने cpuid
eax
आउटपुट दोनों gcc
विस्तारित असेंबली और gdb
में x86-64 असेंबली प्रोग्राम चलाने के साथ पुष्टि की है। सभी eax
और ecx
में समान मानों के लिए समान परिणाम देते हैं।
संपादित करें: बदल समारोह & VOP get-cpuid-eax
के नाम चर नाम के साथ भ्रम से बचने के।
संपादित करें: स्लिम के साथ निश्चित कोड स्वरूपण।
(sb-vm::defknown get-cpuid-eax
((unsigned-byte 32) (unsigned-byte 32))
(unsigned-byte 32)
(sb-c::foldable sb-c::flushable sb-c::movable))
(sb-vm::define-vop (get-cpuid-eax)
(:policy :fast-safe)
(:translate get-cpuid-eax)
(:args
(my-eax :scs (sb-vm::unsigned-reg) :target eax)
(my-ecx :scs (sb-vm::unsigned-reg) :target ecx))
(:arg-types sb-vm::unsigned-num sb-vm::unsigned-num)
(:temporary
(:sc sb-vm::unsigned-reg :offset sb-vm::eax-offset)
eax)
(:temporary
(:sc sb-vm::unsigned-reg :offset sb-vm::ecx-offset)
ecx)
(:results
(my-result :scs (sb-vm::unsigned-reg)))
(:result-types sb-vm::unsigned-num)
(:generator
0
(sb-vm::move eax my-eax)
(sb-vm::move ecx my-ecx)
(sb-vm::inst cpuid)
(sb-vm::move my-result eax)))
(defun get-cpuid-eax (my-eax my-ecx)
(declare (type (unsigned-byte 32) my-eax my-ecx)
(optimize (speed 3) (safety 0)))
(defparameter *result* (get-cpuid-eax my-eax my-ecx)))
जो मैं बहुत उपयोगी पाया है, जबकि इस कोडिंग कम VOPs साथ कुछ वेबसाइटों:
Dmitry Kaliyanov's article "Добавление примитивов виртуальной машины SBCL" ("Adding primitive virtual machines of SBCL", in Russian)
the Lisp code for Dmitry Kaliyanov's article (above)
Dmitry Ignatiev's blog entry: SBCL, x86, SSE (in Russian)
Christophe Rhodes' presentation slides (pdf): Unportable but fun: Using SBCL Internals
kurohuku's blog entry: "SBCLでCPUID" (in Japanese)
swap-bytes source code file sbcl-vops.lisp
आशा इस मदद करता है।
क्या आप के लिए यह आवश्यकता क्यों है? लिस्प फ़ंक्शन के बीच में, आप कभी भी यह सुनिश्चित नहीं कर सकते कि एक विशिष्ट रजिस्टर की सामग्री को मुद्रित करने के लिए एक विशिष्ट रजिस्टर का उपयोग क्यों किया जा रहा है, इससे अधिक समझ नहीं आएगी। –
कृपया स्पष्ट करें कि आपको एक सीपीयू रजिस्टर के मूल्य को जानने की आवश्यकता क्यों है। आम तौर पर, रजिस्टर मानों को जानना बहुत उपयोगी नहीं है क्योंकि उन्हें कंपाइलर द्वारा प्रबंधित किया जाता है। एसबीसीएल में आप असेंबली कोड के साथ वीओपी (वर्चुअल मशीन ऑपरेशन) को परिभाषित कर सकते हैं - http://sbcl-internals.cliki.net/Adding%20VOP देखें । –
मैं एक बफर ओवरफ्लो के लिए कमजोर प्रोग्राम लिखने की कोशिश कर रहा हूं, और स्टैक पर वापसी पते को ओवरराइट करके इसका शोषण करने के लिए कोड। –