📄 insts.lisp
字号:
(xchg-acc-with-something operand1 operand2)) ((accumulator-p operand2) (xchg-acc-with-something operand2 operand1)) ((register-p operand1) (xchg-reg-with-something operand1 operand2)) ((register-p operand2) (xchg-reg-with-something operand2 operand1)) (t (error "bogus args to XCHG: ~S ~S" operand1 operand2)))))))(define-instruction lea (segment dst src) (:printer reg-reg/mem ((op #b1000110) (width 1))) (:emitter (aver (dword-reg-p dst)) (emit-byte segment #b10001101) (emit-ea segment src (reg-tn-encoding dst))))(define-instruction cmpxchg (segment dst src &optional prefix) ;; Register/Memory with Register. (:printer ext-reg-reg/mem ((op #b1011000)) '(:name :tab reg/mem ", " reg)) (:emitter (aver (register-p src)) (emit-prefix segment prefix) (let ((size (matching-operand-size src dst))) (maybe-emit-operand-size-prefix segment size) (emit-byte segment #b00001111) (emit-byte segment (if (eq size :byte) #b10110000 #b10110001)) (emit-ea segment dst (reg-tn-encoding src)))))(defun emit-prefix (segment name) (ecase name ((nil)) (:lock #!+sb-thread (emit-byte segment #xf0)) (:fs (emit-byte segment #x64)) (:gs (emit-byte segment #x65))))(define-instruction fs-segment-prefix (segment) (:printer byte ((op #b01100100))) (:emitter (bug "FS emitted as a separate instruction!")))(define-instruction gs-segment-prefix (segment) (:printer byte ((op #b01100101))) (:emitter (bug "GS emitted as a separate instruction!")));;;; flag control instructions;;; CLC -- Clear Carry Flag.(define-instruction clc (segment) (:printer byte ((op #b11111000))) (:emitter (emit-byte segment #b11111000)));;; CLD -- Clear Direction Flag.(define-instruction cld (segment) (:printer byte ((op #b11111100))) (:emitter (emit-byte segment #b11111100)));;; CLI -- Clear Iterrupt Enable Flag.(define-instruction cli (segment) (:printer byte ((op #b11111010))) (:emitter (emit-byte segment #b11111010)));;; CMC -- Complement Carry Flag.(define-instruction cmc (segment) (:printer byte ((op #b11110101))) (:emitter (emit-byte segment #b11110101)));;; LAHF -- Load AH into flags.(define-instruction lahf (segment) (:printer byte ((op #b10011111))) (:emitter (emit-byte segment #b10011111)));;; POPF -- Pop flags.(define-instruction popf (segment) (:printer byte ((op #b10011101))) (:emitter (emit-byte segment #b10011101)));;; PUSHF -- push flags.(define-instruction pushf (segment) (:printer byte ((op #b10011100))) (:emitter (emit-byte segment #b10011100)));;; SAHF -- Store AH into flags.(define-instruction sahf (segment) (:printer byte ((op #b10011110))) (:emitter (emit-byte segment #b10011110)));;; STC -- Set Carry Flag.(define-instruction stc (segment) (:printer byte ((op #b11111001))) (:emitter (emit-byte segment #b11111001)));;; STD -- Set Direction Flag.(define-instruction std (segment) (:printer byte ((op #b11111101))) (:emitter (emit-byte segment #b11111101)));;; STI -- Set Interrupt Enable Flag.(define-instruction sti (segment) (:printer byte ((op #b11111011))) (:emitter (emit-byte segment #b11111011)));;;; arithmetic(defun emit-random-arith-inst (name segment dst src opcode &optional allow-constants) (let ((size (matching-operand-size dst src))) (maybe-emit-operand-size-prefix segment size) (cond ((integerp src) (cond ((and (not (eq size :byte)) (<= -128 src 127)) (emit-byte segment #b10000011) (emit-ea segment dst opcode allow-constants) (emit-byte segment src)) ((accumulator-p dst) (emit-byte segment (dpb opcode (byte 3 3) (if (eq size :byte) #b00000100 #b00000101))) (emit-sized-immediate segment size src)) (t (emit-byte segment (if (eq size :byte) #b10000000 #b10000001)) (emit-ea segment dst opcode allow-constants) (emit-sized-immediate segment size src)))) ((register-p src) (emit-byte segment (dpb opcode (byte 3 3) (if (eq size :byte) #b00000000 #b00000001))) (emit-ea segment dst (reg-tn-encoding src) allow-constants)) ((register-p dst) (emit-byte segment (dpb opcode (byte 3 3) (if (eq size :byte) #b00000010 #b00000011))) (emit-ea segment src (reg-tn-encoding dst) allow-constants)) (t (error "bogus operands to ~A" name)))))(eval-when (:compile-toplevel :execute) (defun arith-inst-printer-list (subop) `((accum-imm ((op ,(dpb subop (byte 3 2) #b0000010)))) (reg/mem-imm ((op (#b1000000 ,subop)))) (reg/mem-imm ((op (#b1000001 ,subop)) (imm nil :type signed-imm-byte))) (reg-reg/mem-dir ((op ,(dpb subop (byte 3 1) #b000000)))))) )(define-instruction add (segment dst src &optional prefix) (:printer-list (arith-inst-printer-list #b000)) (:emitter (emit-prefix segment prefix) (emit-random-arith-inst "ADD" segment dst src #b000)))(define-instruction adc (segment dst src) (:printer-list (arith-inst-printer-list #b010)) (:emitter (emit-random-arith-inst "ADC" segment dst src #b010)))(define-instruction sub (segment dst src &optional prefix) (:printer-list (arith-inst-printer-list #b101)) (:emitter (emit-prefix segment prefix) (emit-random-arith-inst "SUB" segment dst src #b101)))(define-instruction sbb (segment dst src) (:printer-list (arith-inst-printer-list #b011)) (:emitter (emit-random-arith-inst "SBB" segment dst src #b011)))(define-instruction cmp (segment dst src &optional prefix) (:printer-list (arith-inst-printer-list #b111)) (:emitter (emit-prefix segment prefix) (emit-random-arith-inst "CMP" segment dst src #b111 t)))(define-instruction inc (segment dst) ;; Register. (:printer reg-no-width ((op #b01000))) ;; Register/Memory (:printer reg/mem ((op '(#b1111111 #b000)))) (:emitter (let ((size (operand-size dst))) (maybe-emit-operand-size-prefix segment size) (cond ((and (not (eq size :byte)) (register-p dst)) (emit-byte-with-reg segment #b01000 (reg-tn-encoding dst))) (t (emit-byte segment (if (eq size :byte) #b11111110 #b11111111)) (emit-ea segment dst #b000))))))(define-instruction dec (segment dst) ;; Register. (:printer reg-no-width ((op #b01001))) ;; Register/Memory (:printer reg/mem ((op '(#b1111111 #b001)))) (:emitter (let ((size (operand-size dst))) (maybe-emit-operand-size-prefix segment size) (cond ((and (not (eq size :byte)) (register-p dst)) (emit-byte-with-reg segment #b01001 (reg-tn-encoding dst))) (t (emit-byte segment (if (eq size :byte) #b11111110 #b11111111)) (emit-ea segment dst #b001))))))(define-instruction neg (segment dst) (:printer reg/mem ((op '(#b1111011 #b011)))) (:emitter (let ((size (operand-size dst))) (maybe-emit-operand-size-prefix segment size) (emit-byte segment (if (eq size :byte) #b11110110 #b11110111)) (emit-ea segment dst #b011))))(define-instruction aaa (segment) (:printer byte ((op #b00110111))) (:emitter (emit-byte segment #b00110111)))(define-instruction aas (segment) (:printer byte ((op #b00111111))) (:emitter (emit-byte segment #b00111111)))(define-instruction daa (segment) (:printer byte ((op #b00100111))) (:emitter (emit-byte segment #b00100111)))(define-instruction das (segment) (:printer byte ((op #b00101111))) (:emitter (emit-byte segment #b00101111)))(define-instruction mul (segment dst src) (:printer accum-reg/mem ((op '(#b1111011 #b100)))) (:emitter (let ((size (matching-operand-size dst src))) (aver (accumulator-p dst)) (maybe-emit-operand-size-prefix segment size) (emit-byte segment (if (eq size :byte) #b11110110 #b11110111)) (emit-ea segment src #b100))))(define-instruction imul (segment dst &optional src1 src2) (:printer accum-reg/mem ((op '(#b1111011 #b101)))) (:printer ext-reg-reg/mem ((op #b1010111))) (:printer reg-reg/mem ((op #b0110100) (width 1) (imm nil :type 'signed-imm-word)) '(:name :tab reg ", " reg/mem ", " imm)) (:printer reg-reg/mem ((op #b0110101) (width 1) (imm nil :type 'signed-imm-byte)) '(:name :tab reg ", " reg/mem ", " imm)) (:emitter (flet ((r/m-with-immed-to-reg (reg r/m immed) (let* ((size (matching-operand-size reg r/m)) (sx (and (not (eq size :byte)) (<= -128 immed 127)))) (maybe-emit-operand-size-prefix segment size) (emit-byte segment (if sx #b01101011 #b01101001)) (emit-ea segment r/m (reg-tn-encoding reg)) (if sx (emit-byte segment immed) (emit-sized-immediate segment size immed))))) (cond (src2 (r/m-with-immed-to-reg dst src1 src2)) (src1 (if (integerp src1) (r/m-with-immed-to-reg dst dst src1) (let ((size (matching-operand-size dst src1))) (maybe-emit-operand-size-prefix segment size) (emit-byte segment #b00001111) (emit-byte segment #b10101111) (emit-ea segment src1 (reg-tn-encoding dst))))) (t (let ((size (operand-size dst))) (maybe-emit-operand-size-prefix segment size) (emit-byte segment (if (eq size :byte) #b11110110 #b11110111)) (emit-ea segment dst #b101)))))))(define-instruction div (segment dst src) (:printer accum-reg/mem ((op '(#b1111011 #b110)))) (:emitter (let ((size (matching-operand-size dst src))) (aver (accumulator-p dst)) (maybe-emit-operand-size-prefix segment size) (emit-byte segment (if (eq size :byte) #b11110110 #b11110111)) (emit-ea segment src #b110))))(define-instruction idiv (segment dst src) (:printer accum-reg/mem ((op '(#b1111011 #b111)))) (:emitter (let ((size (matching-operand-size dst src))) (aver (accumulator-p dst)) (maybe-emit-operand-size-prefix segment size) (emit-byte segment (if (eq size :byte) #b11110110 #b11110111)) (emit-ea segment src #b111))))(define-instruction aad (segment) (:printer two-bytes ((op '(#b11010101 #b00001010)))) (:emitter (emit-byte segment #b11010101) (emit-byte segment #b00001010)))(define-instruction aam (segment) (:printer two-bytes ((op '(#b11010100 #b00001010)))) (:emitter (emit-byte segment #b11010100) (emit-byte segment #b00001010)));;; CBW -- Convert Byte to Word. AX <- sign_xtnd(AL)(define-instruction cbw (segment) (:emitter (maybe-emit-operand-size-prefix segment :word) (emit-byte segment #b10011000)));;; CWDE -- Convert Word To Double Word Extened. EAX <- sign_xtnd(AX)(define-instruction cwde (segment) (:emitter (maybe-emit-operand-size-prefix segment :dword) (emit-byte segment #b10011000)));;; CWD -- Convert Word to Double Word. DX:AX <- sign_xtnd(AX)(define-instruction cwd (segment) (:emitter (maybe-emit-operand-size-prefix segment :word) (emit-byte segment #b10011001)));;; CDQ -- Convert Double Word to Quad Word. EDX:EAX <- sign_xtnd(EAX)(define-instruction cdq (segment) (:printer byte ((op #b10011001))) (:emitter (maybe-emit-operand-size-prefix segment :dword) (emit-byte segment #b10011001)))(define-instruction xadd (segment dst src &optional prefix) ;; Register/Memory with Register. (:printer ext-reg-reg/mem ((op #b1100000)) '(:name :tab reg/mem ", " reg)) (:emitter (aver (register-p src)) (emit-prefix segment prefix) (let ((size (matching-operand-size src dst))) (maybe-emit-operand-size-prefix segment size) (emit-byte segment #b00001111) (emit-byte segment (if (eq size :byte) #b11000000 #b11000001)) (emit-ea segment dst (reg-tn-encoding src)))))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -