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

Sam*_*ard 8 assembly x86-64 sbcl common-lisp cpu-registers

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

我必须使用gdb吗?

nrz*_*nrz 11

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

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

注意:有一些问题(SBCL或我的代码中的错误?)导致此代码不会始终没有问题地执行.重新编译和重新加载通常有帮助.我已经证实了cpuid eax具有输出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的网站,我发现在编写此代码时非常有用:

梅德Kaliyanov的文章"ДобавлениепримитивоввиртуальноймашиныSBCL"("添加SBCL的原始虚拟机",在俄语)

Dmitry Kaliyanov的文章(上图)的Lisp代码

Dmitry Ignatiev的博客文章:SBCL,x86,SSE(俄文)

Christophe Rhodes的演示幻灯片(pdf):不可移植但有趣:使用SBCL内部

kurohuku的博客文章:"SBCLでCPUID"(日文)

swap-bytes源代码文件sbcl-vops.lisp

希望这可以帮助.