有没有办法让sbcl打印出CPU寄存器的值?

时间:2013-03-11 23:11:59

标签: assembly common-lisp x86-64 cpu-registers sbcl

有没有办法让SBCL在我的程序中的某一点获取CPU寄存器的值并将其打印为整数?

我是否必须使用gdb?

2 个答案:

答案 0 :(得分:11)

是的,您可以使用VOPs (Virtual Operations)访问CPU寄存器。在VOP中你也可以在汇编中编写代码,所以在这个意义上你可以使用像gcc扩展汇编这样的VOP。

所以,这是一个示例VOP和执行它的相关函数。 get-cpuid-eax VOP接收两个无符号32位参数作为输入,将它们存储在eaxecx中,执行cpuid指令,并返回eax的值在调用VOP的cpuidget-cpuid-eax函数之后注册。然后get-cpuid-eax函数将值存储在*result*中。您可以使用(format t "~a" *result*)轻松打印值。

注意:有一些问题(SBCL或我的代码中的错误?)会导致此代码无法始终执行而不会出现问题。重新编译和重新加载通常有帮助。我已使用cpuid扩展程序集并在eax中运行x86-64程序集程序确认了gcc 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

希望这有帮助。

答案 1 :(得分:1)

cpuid示例的另一个来源(也支持64位)来自CL的优秀stmx库。