4 ms·
You might have an idea on this but how would you approach the opposite operation? Assembly to an in-memory representation, how does Lisp/Scheme handle that kind
by speps 7y ago
You might have an idea on this but how would you approach the opposite operation? Assembly to an in-memory representation, how does Lisp/Scheme handle that kind of manipulation?
- siraben 7y agoDo you mean how opcodes are represented in Lisp-based assemblers?
- speps 7y agoNo I mean a disassembler, I can see how an assembler is nice to write in a language like that but I've never seen much byte manipulation examples. For example going from machine code to the list of opcodes for example.
- siraben 7y agoThat would be an interesting project. AFAIK Emacs has a bytecode disassembler[0] but I'm not aware of disassemblers for other instruction sets. [0] https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/emacs-lisp/disass.el https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/emacs-...
- pjmlp 7y agoThere you go, "CHIP-8 in Common Lisp: Disassembly" https://stevelosh.com/blog/2017/01/chip8-disassembly/ https://stevelosh.com/blog/2017/01/chip8-disassembly/
- lispm 7y agoEvery Common Lisp has a DISASSEMBLE function built-in. Compile a function and call the disassembler. For example SBCL https://github.com/sbcl/sbcl/blob/master/src/compiler/disassem.lisp https://github.com/sbcl/sbcl/blob/master/src/compiler/disass... and its ARM64 instructions: https://github.com/sbcl/sbcl/blob/master/src/compiler/arm64/insts.lisp https://github.com/sbcl/sbcl/blob/master/src/compiler/arm64/...
- dreamcompiler 7y agoHere's the times13 function in CCL on x86-64. (Note that #x68 is 13 shifted left 3 times to allow tag bits in the LS 3 bit positions. Also the below could be optimized a lot more but this is the default compilation.) ? (defun times13 (x) (* 13 x)) TIMES13 ? (disassemble 'times13) ;;; (defun times13 (x) (* 13 x)) (recover-fn-from-rip) ; [0] (cmpl ($ 8) (% nargs)) ; [7] (jne L41) ; [10] (pushq (% rbp)) ; [12] (movq (% rsp) (% rbp)) ; [13] (pushq (% arg_z)) ; [16] ;;; (* 13 x) (movl ($ #x68) (% arg_y.l)) ; [17] (movq (@ -8 (% rbp)) (% arg_z)) ; [22] (movq (% rbp) (% rsp)) ; [26] (popq (% rbp)) ; [29] (jmp (@ .SPBUILTIN-TIMES)) ; [30] ;;; #<no source text> (:align 3) L41 ; [@56] (uuo-error-wrong-number-of-args) ; [41] NIL
- aidenn0 7y agoWith the BYTE accessors and binary constants, I find bit and byte manipulation to be far easier in common-lisp than in C. e.g. set the 3 bytes starting at bit 2 of x to the binary value 110: (setf (ldb (byte 3 2) x) #b110) or set the 3rd byte (8 bits starting at bit 24) of x to 0xab: (setf (ldb (byte 8 24) x) #xab) The first example compiles down to the following 2 instructions on sbcl/x64: ; A4: 4883E1C6 AND RCX, -58 ; A8: 4883C930 OR RCX, 48 NOTE: The values are 1 bit shifted from what you might expect (binary 110 = 6; 6 << 2 == 24, not 48) because SBCL uses low-bit tagging to distinguish integers from pointers; working with arrays of unboxed machine-friendly sized integers (8,32,64) works as expected.