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

📄 insts.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 5 页
字号:
                                  nil))                               (#b01                                (sb!disassem:read-signed-suffix 8 dstate))                               (#b10                                (sb!disassem:read-signed-suffix 32 dstate)))))                   (list (unless (and (= mod #b00) (= base-reg #b101))                           (if (sb!disassem:dstate-get-inst-prop dstate 'rex-b)                               (+ base-reg 8)                               base-reg))                         offset                         (unless (= index-reg #b100)                           (if (sb!disassem:dstate-get-inst-prop dstate 'rex-x)                               (+ index-reg 8)                               index-reg))                         (ash 1 index-scale))))))            ((and (= mod #b00) (= r/m #b101))             (list 'rip (sb!disassem:read-signed-suffix 32 dstate)))            ((= mod #b00)             (list full-reg))            ((= mod #b01)           (list full-reg (sb!disassem:read-signed-suffix 8 dstate)))          (t                            ; (= mod #b10)           (list full-reg (sb!disassem:read-signed-suffix 32 dstate)))))))(defun read-address (value dstate)  (declare (ignore value))              ; always nil anyway  (sb!disassem:read-suffix (width-bits (inst-operand-size dstate)) dstate))(defun width-bits (width)  (ecase width    (:byte 8)    (:word 16)    (:dword 32)    (:qword 64)))) ; EVAL-WHEN;;;; disassembler argument types;;; Used to capture the lower four bits of the REX prefix.(sb!disassem:define-arg-type wrxb  :prefilter #'prefilter-wrxb)(sb!disassem:define-arg-type width  :prefilter #'prefilter-width  :printer (lambda (value stream dstate)             (declare (ignore value))             (princ (schar (symbol-name (inst-operand-size dstate)) 0)                    stream)));;; Used to capture the effect of the #x66 operand size override prefix.(sb!disassem:define-arg-type x66  :prefilter #'prefilter-x66)(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 reg  :prefilter #'prefilter-reg-r  :printer #'print-reg)(sb!disassem:define-arg-type reg-b  :prefilter #'prefilter-reg-b  :printer #'print-reg)(sb!disassem:define-arg-type reg-b-default-qword  :prefilter #'prefilter-reg-b  :printer #'print-reg-default-qword)(sb!disassem:define-arg-type imm-addr  :prefilter #'read-address  :printer #'print-label);;; Normally, immediate values for an operand size of :qword are of size;;; :dword and are sign-extended to 64 bits. For an exception, see the;;; argument type definition following this one.(sb!disassem:define-arg-type signed-imm-data  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (let ((width (width-bits (inst-operand-size dstate))))                 (when (= width 64)                   (setf width 32))                 (sb!disassem:read-signed-suffix width dstate))));;; Used by the variant of the MOV instruction with opcode B8 which can;;; move immediates of all sizes (i.e. including :qword) into a;;; register.(sb!disassem:define-arg-type signed-imm-data-upto-qword  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (sb!disassem:read-signed-suffix                (width-bits (inst-operand-size dstate))                dstate)));;; Used by those instructions that have a default operand size of;;; :qword. Nevertheless the immediate is at most of size :dword.;;; The only instruction of this kind having a variant with an immediate;;; argument is PUSH.(sb!disassem:define-arg-type signed-imm-data-default-qword  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (let ((width (width-bits                             (inst-operand-size-default-qword dstate))))                 (when (= width 64)                   (setf width 32))                 (sb!disassem:read-signed-suffix 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 imm-byte  :prefilter (lambda (value dstate)               (declare (ignore value)) ; always nil anyway               (sb!disassem:read-suffix 8 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);;; Arguments of type reg/mem with a fixed size.(sb!disassem:define-arg-type sized-byte-reg/mem  :prefilter #'prefilter-reg/mem  :printer #'print-sized-byte-reg/mem)(sb!disassem:define-arg-type sized-word-reg/mem  :prefilter #'prefilter-reg/mem  :printer #'print-sized-word-reg/mem)(sb!disassem:define-arg-type sized-dword-reg/mem  :prefilter #'prefilter-reg/mem  :printer #'print-sized-dword-reg/mem);;; Same as sized-reg/mem, but with a default operand size of :qword.(sb!disassem:define-arg-type sized-reg/mem-default-qword  :prefilter #'prefilter-reg/mem  :printer #'print-sized-reg/mem-default-qword);;; XMM registers(sb!disassem:define-arg-type xmmreg  :prefilter #'prefilter-reg-r  :printer #'print-xmmreg)(sb!disassem:define-arg-type xmmreg/mem  :prefilter #'prefilter-reg/mem  :printer #'print-xmmreg/mem)(sb!disassem:define-arg-type sized-xmmreg/mem  :prefilter #'prefilter-reg/mem  :printer #'print-sized-xmmreg/mem)(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(eval-when (:compile-toplevel :execute)  (defun swap-if (direction field1 separator field2)    `(:if (,direction :constant 0)          (,field1 ,separator ,field2)          (,field2 ,separator ,field1))))(sb!disassem:define-instruction-format (byte 8 :default-printer '(:name))  (op    :field (byte 8 0))  ;; optional fields  (accum :type 'accum)  (imm))(sb!disassem:define-instruction-format (two-bytes 16                                        :default-printer '(:name))  (op :fields (list (byte 8 0) (byte 8 8))));;; A one-byte instruction with a #x66 prefix, used to indicate an;;; operand size of :word.(sb!disassem:define-instruction-format (x66-byte 16                                        :default-printer '(:name))  (x66   :field (byte 8 0) :value #x66)  (op    :field (byte 8 8)));;; A one-byte instruction with a REX prefix, used to indicate an;;; operand size of :qword. REX.W must be 1, the other three bits are;;; ignored.(sb!disassem:define-instruction-format (rex-byte 16                                        :default-printer '(:name))  (rex   :field (byte 5 3) :value #b01001)  (op    :field (byte 8 8)))(sb!disassem:define-instruction-format (simple 8)  (op    :field (byte 7 1))  (width :field (byte 1 0) :type 'width)  ;; optional fields  (accum :type 'accum)  (imm))(sb!disassem:define-instruction-format (rex-simple 16)  (rex     :field (byte 4 4)    :value #b0100)  (wrxb    :field (byte 4 0)    :type 'wrxb)  (op    :field (byte 7 9))  (width :field (byte 1 8) :type 'width)  ;; optional fields  (accum :type 'accum)  (imm));;; Same as simple, but with direction bit(sb!disassem:define-instruction-format (simple-dir 8 :include 'simple)  (op :field (byte 6 2))  (dir :field (byte 1 1)));;; Same as simple, but with the immediate value occurring by default,;;; and with an appropiate printer.(sb!disassem:define-instruction-format (accum-imm 8                                     :include 'simple                                     :default-printer '(:name                                                        :tab accum ", " imm))  (imm :type 'signed-imm-data))(sb!disassem:define-instruction-format (rex-accum-imm 16                                     :include 'rex-simple                                     :default-printer '(:name                                                        :tab accum ", " imm))  (imm :type 'signed-imm-data))(sb!disassem:define-instruction-format (reg-no-width 8                                     :default-printer '(:name :tab reg))  (op    :field (byte 5 3))  (reg   :field (byte 3 0) :type 'reg-b)  ;; optional fields  (accum :type 'accum)  (imm))(sb!disassem:define-instruction-format (rex-reg-no-width 16                                     :default-printer '(:name :tab reg))  (rex     :field (byte 4 4)    :value #b0100)  (wrxb    :field (byte 4 0)    :type 'wrxb)  (op      :field (byte 5 11))  (reg     :field (byte 3 8)    :type 'reg-b)  ;; optional fields  (accum :type 'accum)  (imm));;; Same as reg-no-width, but with a default operand size of :qword.(sb!disassem:define-instruction-format (reg-no-width-default-qword 8                                        :include 'reg-no-width                                        :default-printer '(:name :tab reg))  (reg   :type 'reg-b-default-qword));;; Same as rex-reg-no-width, but with a default operand size of :qword.(sb!disassem:define-instruction-format (rex-reg-no-width-default-qword 16                                        :include 'rex-reg-no-width                                        :default-printer '(:name :tab reg))  (reg     :type 'reg-b-default-qword));;; Adds a width field to reg-no-width. Note that we can't use;;; :INCLUDE 'REG-NO-WIDTH here to save typing because that would put;;; the WIDTH field last, but the prefilter for WIDTH must run before;;; the one for IMM to be able to determine the correct size of IMM.(sb!disassem:define-instruction-format (reg 8                                        :default-printer '(:name :tab reg))  (op    :field (byte 4 4))  (width :field (byte 1 3) :type 'width)  (reg   :field (byte 3 0) :type 'reg-b)  ;; optional fields  (accum :type 'accum)  (imm))

⌨️ 快捷键说明

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