2013-03-11 73 views
7

有沒有一種方法可以讓SBCL在我的程序的某個位置獲取CPU寄存器的值並將其作爲整數打印?有沒有辦法讓sbcl打印出CPU寄存器的值?

我需要使用gdb嗎?

+4

你需要什麼用的?在Lisp函數的中間,你永遠無法確定使用了什麼特定的寄存器,因此打印特定寄存器的內容沒有多大意義。 – 2013-03-12 02:55:54

+2

請說明爲什麼您需要知道CPU寄存器的值。一般來說,知道寄存器值並不是非常有用,因爲它們是由編譯器管理的。在SBCL中,您可以使用匯編代碼定義VOP(虛擬機操作) - 請參閱http://sbcl-internals.cliki.net/Adding%20VOPs 。 – 2013-03-12 05:52:39

+0

我想寫一個程序容易受到緩衝區溢出,並通過覆蓋堆棧上的返回地址來利用它的代碼。 – 2013-03-12 17:02:01

回答

10

是的,您可以使用VOPs (Virtual Operations)訪問CPU寄存器。在VOP中,你也可以在彙編中編寫代碼,所以在這個意義上你可以使用VCP如gcc擴展彙編。

所以,這裏有一個VOP例子和一個執行它的相關函數。所述get-cpuid-eax VOP接收兩個32位無符號的參數作爲輸入,將它們存儲在eaxecx,執行cpuid指令,並返回eax寄存器的cpuidget-cpuid-eax函數調用該VOP之後的值。然後get-cpuid-eax函數將值存儲在*result*中。您可以使用(format t "~a" *result*)輕鬆打印該值。

注意:有一些問題(SBCL或我的代碼中的錯誤?),導致此代碼不會執行沒有問題總是。重新編譯和重新加載通常會有所幫助。我已確認cpuideax輸出與gcc擴展程序集和運行x86-64程序集在gdb。對於eaxecx中的相同值,所有結果都相同。

編輯:改變功能& VOP名稱爲get-cpuid-eax,以避免與變量名稱混淆。

編輯:固定代碼格式與slimv。

 
(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))) 

一些短的VOP的網站,我發現非常有用的,而這個編碼:

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

希望這有助於。

+0

爲什麼你將結果存儲在'* result *'中而不是返回?爲什麼在defun中有一個'defparameter'? 「(安全0)」有特殊原因嗎? – 2018-01-26 01:01:59

+0

@DanRobertson我的答案是概念證明(可以完成),而不是企業級代碼。您可以自由發佈自己的答案。 – nrz 2018-01-26 06:19:14

+0

我想我期待的答覆是「如果你不做X,那麼VOP不會踢」 – 2018-01-26 09:59:31

相關問題