Memory 将操作码插入内存

Memory 将操作码插入内存,memory,assembly,lisp,common-lisp,nasm,Memory,Assembly,Lisp,Common Lisp,Nasm,嗨,我想知道是否有可能将指令操作码“插入”到内存中,或者如何将它们转换成二进制程序。我在这里发现了一个废弃的lisp项目:它接受x86 asm指令并将其转换为操作码(请参见下面的示例)。该项目没有进一步实际完成二进制可执行文件的创建。因此,我需要“手动”这样做,任何想法都可以帮助我。谢谢 ;; assemble some code in it (cl-x86-asm::assemble-forms '((.Entry :PUSH :EAX) (:SUB :EAX #XFFFEA)

嗨,我想知道是否有可能将指令操作码“插入”到内存中,或者如何将它们转换成二进制程序。我在这里发现了一个废弃的lisp项目:它接受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

例如,Clozure Common Lisp就内置了这种功能。这通常称为LAP,Lisp汇编程序

请参见
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(虚拟操作)执行一些类似的操作


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

(:movl 12 :eax)
(:ret)
这将转换为以下八位字节序列:#(184 12 0 0 0 195),十六进制形式为:#(B8 C 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频道)的专家帮助解决此问题。

感谢Rainier,这是两个很好的例子。我上面提到的那个库的优点是可移植性,因为它不依赖于具体的实现细节。@francogrex:当然,但你没有要求一个可移植库。你问这是否可能。也许你应该重新表述你的问题?我正在考虑一些类似Basic的POKE命令的东西,将机器代码直接插入RAM中:在标准的Common Lisp中没有这样的东西。我知道这是一个非常古老的答案,但是你在回答的第一部分使用什么从程序集生成向量?cffi支持吗?@Joshua尽管有些Lisp可以将某些函数反汇编成操作码,但cffi不能也不能生成汇编操作码。您需要阅读并使用硬件说明手册。