⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 insts.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 5 页
字号:
;;;; that part of the description of the x86 instruction set (for;;;; 80386 and above) which can live on the cross-compilation host;;;; This software is part of the SBCL system. See the README file for;;;; more information.;;;;;;;; This software is derived from the CMU CL system, which was;;;; written at Carnegie Mellon University and released into the;;;; public domain. The software is in the public domain and is;;;; provided with absolutely no warranty. See the COPYING and CREDITS;;;; files for more information.(in-package "SB!VM");;; FIXME: SB!DISASSEM: prefixes are used so widely in this file that;;; I wonder whether the separation of the disassembler from the;;; virtual machine is valid or adds value.;;; Note: In CMU CL, this used to be a call to SET-DISASSEM-PARAMS.(setf sb!disassem:*disassem-inst-alignment-bytes* 1)(deftype reg () '(unsigned-byte 3))(def!constant +default-operand-size+ :dword)(eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)(defun offset-next (value dstate)  (declare (type integer value)           (type sb!disassem:disassem-state dstate))  (+ (sb!disassem:dstate-next-addr dstate) value))(defparameter *default-address-size*  ;; Actually, :DWORD is the only one really supported.  :dword)(defparameter *byte-reg-names*  #(al cl dl bl ah ch dh bh))(defparameter *word-reg-names*  #(ax cx dx bx sp bp si di))(defparameter *dword-reg-names*  #(eax ecx edx ebx esp ebp esi edi))(defun print-reg-with-width (value width stream dstate)  (declare (ignore dstate))  (princ (aref (ecase width                 (:byte *byte-reg-names*)                 (:word *word-reg-names*)                 (:dword *dword-reg-names*))               value)         stream)  ;; XXX plus should do some source-var notes  )(defun print-reg (value stream dstate)  (declare (type reg value)           (type stream stream)           (type sb!disassem:disassem-state dstate))  (print-reg-with-width value                        (sb!disassem:dstate-get-prop dstate 'width)                        stream                        dstate))(defun print-word-reg (value stream dstate)  (declare (type reg value)           (type stream stream)           (type sb!disassem:disassem-state dstate))  (print-reg-with-width value                        (or (sb!disassem:dstate-get-prop dstate 'word-width)                            +default-operand-size+)                        stream                        dstate))(defun print-byte-reg (value stream dstate)  (declare (type reg value)           (type stream stream)           (type sb!disassem:disassem-state dstate))  (print-reg-with-width value :byte stream dstate))(defun print-addr-reg (value stream dstate)  (declare (type reg value)           (type stream stream)           (type sb!disassem:disassem-state dstate))  (print-reg-with-width value *default-address-size* stream dstate))(defun print-reg/mem (value stream dstate)  (declare (type (or list reg) value)           (type stream stream)           (type sb!disassem:disassem-state dstate))  (if (typep value 'reg)      (print-reg value stream dstate)      (print-mem-access value stream nil dstate)));; Same as print-reg/mem, but prints an explicit size indicator for;; memory references.(defun print-sized-reg/mem (value stream dstate)  (declare (type (or list reg) value)           (type stream stream)           (type sb!disassem:disassem-state dstate))  (if (typep value 'reg)      (print-reg value stream dstate)      (print-mem-access value stream t dstate)))(defun print-byte-reg/mem (value stream dstate)  (declare (type (or list reg) value)           (type stream stream)           (type sb!disassem:disassem-state dstate))  (if (typep value 'reg)      (print-byte-reg value stream dstate)      (print-mem-access value stream t dstate)))(defun print-word-reg/mem (value stream dstate)  (declare (type (or list reg) value)           (type stream stream)           (type sb!disassem:disassem-state dstate))  (if (typep value 'reg)      (print-word-reg value stream dstate)      (print-mem-access value stream nil dstate)))(defun print-label (value stream dstate)  (declare (ignore dstate))  (sb!disassem:princ16 value stream));;; Returns either an integer, meaning a register, or a list of;;; (BASE-REG OFFSET INDEX-REG INDEX-SCALE), where any component;;; may be missing or nil to indicate that it's not used or has the;;; obvious default value (e.g., 1 for the index-scale).(defun prefilter-reg/mem (value dstate)  (declare (type list value)           (type sb!disassem:disassem-state dstate))  (let ((mod (car value))        (r/m (cadr value)))    (declare (type (unsigned-byte 2) mod)             (type (unsigned-byte 3) r/m))    (cond ((= mod #b11)           ;; registers           r/m)          ((= r/m #b100)           ;; sib byte           (let ((sib (sb!disassem:read-suffix 8 dstate)))             (declare (type (unsigned-byte 8) sib))             (let ((base-reg (ldb (byte 3 0) sib))                   (index-reg (ldb (byte 3 3) sib))                   (index-scale (ldb (byte 2 6) sib)))               (declare (type (unsigned-byte 3) base-reg index-reg)                        (type (unsigned-byte 2) index-scale))               (let* ((offset                       (case mod                         (#b00                          (if (= base-reg #b101)                              (sb!disassem:read-signed-suffix 32 dstate)                              nil))                         (#b01                          (sb!disassem:read-signed-suffix 8 dstate))                         (#b10                          (sb!disassem:read-signed-suffix 32 dstate)))))                 (list (if (and (= mod #b00) (= base-reg #b101)) nil base-reg)                       offset                       (if (= index-reg #b100) nil index-reg)                       (ash 1 index-scale))))))          ((and (= mod #b00) (= r/m #b101))           (list nil (sb!disassem:read-signed-suffix 32 dstate)) )          ((= mod #b00)           (list r/m))          ((= mod #b01)           (list r/m (sb!disassem:read-signed-suffix 8 dstate)))          (t                            ; (= mod #b10)           (list r/m (sb!disassem:read-signed-suffix 32 dstate))))));;; This is a sort of bogus prefilter that just stores the info globally for;;; other people to use; it probably never gets printed.(defun prefilter-width (value dstate)  (setf (sb!disassem:dstate-get-prop dstate 'width)        (if (zerop value)            :byte            (let ((word-width                   ;; set by a prefix instruction                   (or (sb!disassem:dstate-get-prop dstate 'word-width)                       +default-operand-size+)))              (when (not (eql word-width +default-operand-size+))                ;; Reset it.                (setf (sb!disassem:dstate-get-prop dstate 'word-width)                      +default-operand-size+))              word-width))))(defun read-address (value dstate)  (declare (ignore value))              ; always nil anyway  (sb!disassem:read-suffix (width-bits *default-address-size*) dstate))(defun width-bits (width)  (ecase width    (:byte 8)    (:word 16)    (:dword 32)    (:float 32)    (:double 64)))) ; EVAL-WHEN;;;; disassembler argument types(sb!disassem:define-arg-type displacement  :sign-extend t  :use-label #'offset-next  :printer (lambda (value stream dstate)             (sb!disassem:maybe-note-assembler-routine value nil dstate)             (print-label value stream dstate)))(sb!disassem:define-arg-type accum  :printer (lambda (value stream dstate)             (declare (ignore value)                      (type stream stream)                      (type sb!disassem:disassem-state dstate))             (print-reg 0 stream dstate)))(sb!disassem:define-arg-type word-accum  :printer (lambda (value stream dstate)             (declare (ignore value)                      (type stream stream)                      (type sb!disassem:disassem-state dstate))             (print-word-reg 0 stream dstate)))(sb!disassem:define-arg-type reg  :printer #'print-reg)(sb!disassem:define-arg-type addr-reg  :printer #'print-addr-reg)(sb!disassem:define-arg-type word-reg  :printer #'print-word-reg)(sb!disassem:define-arg-type imm-addr  :prefilter #'read-address  :printer #'print-label)(sb!disassem:define-arg-type imm-data  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (sb!disassem:read-suffix                (width-bits (sb!disassem:dstate-get-prop dstate 'width))                dstate)))(sb!disassem:define-arg-type signed-imm-data  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (let ((width (sb!disassem:dstate-get-prop dstate 'width)))                 (sb!disassem:read-signed-suffix (width-bits width) dstate))))(sb!disassem:define-arg-type signed-imm-byte  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (sb!disassem:read-signed-suffix 8 dstate)))(sb!disassem:define-arg-type signed-imm-dword  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (sb!disassem:read-signed-suffix 32 dstate)))(sb!disassem:define-arg-type imm-word  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (let ((width                      (or (sb!disassem:dstate-get-prop dstate 'word-width)                          +default-operand-size+)))                 (sb!disassem:read-suffix (width-bits width) dstate))))(sb!disassem:define-arg-type signed-imm-word  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (let ((width                      (or (sb!disassem:dstate-get-prop dstate 'word-width)                          +default-operand-size+)))                 (sb!disassem:read-signed-suffix (width-bits width) dstate))));;; needed for the ret imm16 instruction(sb!disassem:define-arg-type imm-word-16  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (sb!disassem:read-suffix 16 dstate)))(sb!disassem:define-arg-type reg/mem  :prefilter #'prefilter-reg/mem  :printer #'print-reg/mem)(sb!disassem:define-arg-type sized-reg/mem  ;; Same as reg/mem, but prints an explicit size indicator for  ;; memory references.  :prefilter #'prefilter-reg/mem  :printer #'print-sized-reg/mem)(sb!disassem:define-arg-type byte-reg/mem  :prefilter #'prefilter-reg/mem  :printer #'print-byte-reg/mem)(sb!disassem:define-arg-type word-reg/mem  :prefilter #'prefilter-reg/mem  :printer #'print-word-reg/mem);;; added by jrd(eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)(defun print-fp-reg (value stream dstate)  (declare (ignore dstate))  (format stream "FR~D" value))(defun prefilter-fp-reg (value dstate)  ;; just return it  (declare (ignore dstate))  value)) ; EVAL-WHEN(sb!disassem:define-arg-type fp-reg                             :prefilter #'prefilter-fp-reg                             :printer #'print-fp-reg)(sb!disassem:define-arg-type width  :prefilter #'prefilter-width  :printer (lambda (value stream dstate)             (if;; (zerop value)                 (or (null value)                     (and (numberp value) (zerop value))) ; zzz jrd                 (princ 'b stream)                 (let ((word-width                        ;; set by a prefix instruction                        (or (sb!disassem:dstate-get-prop dstate 'word-width)                            +default-operand-size+)))                   (princ (schar (symbol-name word-width) 0) stream)))))(eval-when (:compile-toplevel :load-toplevel :execute)(defparameter *conditions*  '((:o . 0)    (:no . 1)    (:b . 2) (:nae . 2) (:c . 2)    (:nb . 3) (:ae . 3) (:nc . 3)    (:eq . 4) (:e . 4) (:z . 4)    (:ne . 5) (:nz . 5)    (:be . 6) (:na . 6)    (:nbe . 7) (:a . 7)    (:s . 8)    (:ns . 9)    (:p . 10) (:pe . 10)    (:np . 11) (:po . 11)    (:l . 12) (:nge . 12)    (:nl . 13) (:ge . 13)    (:le . 14) (:ng . 14)    (:nle . 15) (:g . 15)))(defparameter *condition-name-vec*  (let ((vec (make-array 16 :initial-element nil)))    (dolist (cond *conditions*)      (when (null (aref vec (cdr cond)))        (setf (aref vec (cdr cond)) (car cond))))    vec))) ; EVAL-WHEN;;; Set assembler parameters. (In CMU CL, this was done with;;; a call to a macro DEF-ASSEMBLER-PARAMS.)(eval-when (:compile-toplevel :load-toplevel :execute)  (setf sb!assem:*assem-scheduler-p* nil))(sb!disassem:define-arg-type condition-code  :printer *condition-name-vec*)(defun conditional-opcode (condition)  (cdr (assoc condition *conditions* :test #'eq)));;;; disassembler instruction formats

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -