2013-03-11 15 views
7

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?

+4

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. –

+2

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 . –

+0

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. –

cevap

10

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ı cpuidget-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 cpuideax çı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:

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

Bu yardımcı olur kurohuku's blog entry: "SBCLでCPUID" (in Japanese)

swap-bytes source code file sbcl-vops.lisp

Umut.
+0

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ı? –

+0

@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

+0

Sanırım bir cevap beklemekteydim “eğer X yapmazsanız, o zaman vop asla başlamaz” –

İlgili konular