SBCL'nin programımdaki belirli bir noktada bir CPU yazmacının değerini almasını ve bir tamsayı olarak yazmasını sağlamanın bir yolu var mı?CPU kayıtçısının değerini yazdırmak için sbcl almanın bir yolu var mı?
Gdb kullanmalı mıyım?
SBCL'nin programımdaki belirli bir noktada bir CPU yazmacının değerini almasını ve bir tamsayı olarak yazmasını sağlamanın bir yolu var mı?CPU kayıtçısının değerini yazdırmak için sbcl almanın bir yolu var mı?
Gdb kullanmalı mıyım?
Evet, VOPs (Virtual Operations) kullanarak CPU kayıtlarını erişebilirsiniz. VOP'larda, kodu da montajda yazabilirsiniz, bu nedenle, gcc uzatılmış montaj gibi VOP'ları kullanabilirsiniz.
Yani, burada bir örnek VOP ve bunun yürütülmesiyle ilgili bir işlev var. get-cpuid-eax
VOP, girdi olarak iki işaretsiz bir 32 bit bağımsız değişkenler alır eax
ve ecx
bunları saklar cpuid
talimatı çalıştırır ve VOP adı cpuid
get-cpuid-eax
işlev sonra eax
kaydının değerini verir. get-cpuid-eax
işlevi, değeri *result*
'da saklar. Değeri (format t "~a" *result*)
ile kolayca basabilirsiniz.
Not: her zaman sorunsuz yürütmek için değil bu kodu neden bazı sorun (? SBCL veya benim kodda hata) bulunmaktadır. Yeniden derleme ve yeniden yükleme genellikle yardımcı olur. Hem gcc
genişletilmiş derlemeyle hem de gdb
'da bir x86-64 derleme programını çalıştırarak cpuid
eax
çıktısını doğruladım. Hepsi aynı değerleri eax
ve ecx
içinde verir.
Düzenleme: get-cpuid-eax
için değişti fonksiyon & VOP adları değişken adları ile karışıklığı önlemek için.
Düzenleme: sabit kod slimv ile biçimlendirme.
(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)))
bu kodlama yaparken çok yararlı buldum kısa VOP'lerin ile Bazı web siteleri:
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
Bu yardımcı olur kurohuku's blog entry: "SBCLでCPUID" (in Japanese) Umut.Neden sonucu döndürmek yerine '* sonuç *' içinde saklıyorsunuz? Ve neden bir 'defparameter' bir 'defun' içinde ?! Ve (güvenlik 0) 'ın olması için belirli bir neden var mı? –
@DanRobertson Cevabım, kurumsal düzeyde bir kod değil, kavramın (bu yapılabilir) bir kanıtıdır. Kendi cevabınızı göndermekte özgürsünüz. – nrz
Sanırım bir cevap beklemekteydim “eğer X yapmazsanız, o zaman vop asla başlamaz” –
Bir cpuid örneğinin başka bir kaynağı (64bit'i de destekler) CL için mükemmel stmx kitaplığından gelir.
Ne bunun için gerekli? Lisp işlevinin ortasında, belirli bir sicilin içeriğini yazdırmak için kullanıldığından emin olamazsınız. –
Lütfen bir CPU yazmacının değerini bilmeniz gerektiğini açıklayınız. Genel olarak, derleyici tarafından yönetildiği için kayıt değerlerini bilmek çok yararlı değildir. SBCL'de, montaj kodu ile VOP'ları tanımlayabilirsiniz (bkz. Http://sbcl-internals.cliki.net/Adding%20VOPs . –
Bir arabellek taşmasına karşı korunmasız bir program yazmaya çalışıyorum ve kodun yığın üzerindeki dönüş adresini üzerine yazarak yararlanma kodunu yazdım. –