4

嗨,我想了解是否可以获取指令操作码并将它们“插入”到内存中,或者将它们转换为二进制程序。我在这里找到了一个废弃的 lisp 项目:http: //common-lisp.net/viewvc/cl-x86-asm/cl-x86-asm/它采用 x86 asm 指令并将它们转换为操作码(请参见下面的示例)。该项目没有进一步实际完成二进制可执行文件的创建。因此,我需要“手动”执行此操作,任何想法都可以帮助我。谢谢。

 ;; assemble some code in it
(cl-x86-asm::assemble-forms 
  '((.Entry :PUSH :EAX)
    (:SUB :EAX #XFFFEA)
    (:MOV :EAX :EBX)
    (:POP :EAX)
    (:PUSH :EAX)
    (.Exit :RET))

加工...

;; print the assembled segment
(cl-x86-asm::print-segment)

* Segment type DATA-SEGMENT
Segment size 0000000C bytes
50 81 05 00 0F FF EA 89
03 58 50 C3
4

2 回答 2

5

例如 Clozure Common Lisp 就有这个内置的。这通常称为LAPLisp 汇编程序

defx86lapfunction

例子:

(defx86lapfunction fast-mod ((number arg_y) (divisor arg_z))
  (xorq (% imm1) (% imm1))
  (mov (% number) (% imm0))
  (div (% divisor))
  (mov (% imm1) (% arg_z))
  (single-value-return))

SBCL 可以用VOP(虚拟操作)做一些类似的事情。

http://g000001.cddddr.org/2011-12-08

于 2013-09-03T20:11:45.710 回答
2

我了解到可以使用 CFFI/FFI 来完成,例如非常简单的 asm 代码:

(:movl 12 :eax)
(:ret)

这将被转换为以下八位字节序列:#(184 12 0 0 0 195),十六进制为:#(B8 C 0 0 0 C3)。下一步是将其发送到内存中的某个位置,如下所示:

(defparameter pointer (cffi:foreign-alloc :unsigned-char :initial-contents #(184 12 0 0 0 195)))
;; and then execute it as such to return the integer 12:
(cffi:foreign-funcall-pointer pointer () :int)
=> result: 12

感谢#lisp(freenode irc 频道)的专家帮助解决这个问题。

于 2013-09-22T07:07:16.330 回答