2013-03-11 71 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

相关问题