• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
    • Software-verification
      • Kestrel-books
      • X86isa
        • Program-execution
        • Sdm-instruction-set-summary
        • Tlb
        • Running-linux
        • Introduction
        • Asmtest
        • X86isa-build-instructions
        • Publications
        • Contributors
        • Machine
          • X86isa-state
          • Syscalls
          • Cpuid
          • Linear-memory
          • Rflag-specifications
          • Characterizing-undefined-behavior
          • Top-level-memory
          • App-view
          • X86-decoder
          • Physical-memory
          • Decoding-and-spec-utils
            • Read-operands-and-write-results
            • Effective-address-computations
            • Select-operand-size
            • Instruction-pointer-operations
            • Stack-pointer-operations
              • Add-to-*sp
              • Write-*sp
              • Read-*sp
            • Select-segment-register
            • Prefix-modrm-sib-decoding
            • Select-address-size
            • Rex-byte-from-vex-prefixes
            • Check-instruction-length
            • Error-objects
            • Rip-guard-okp
            • Sib-decoding
          • Instructions
          • Register-readers-and-writers
          • X86-modes
          • Segmentation
          • Other-non-deterministic-computations
          • Environment
          • Paging
        • Implemented-opcodes
        • To-do
        • Proof-utilities
        • Peripherals
        • Model-validation
        • Modelcalls
        • Concrete-simulation-examples
        • Utils
        • Debugging-code-proofs
      • Axe
      • Execloader
    • Math
    • Testing-utilities
  • Decoding-and-spec-utils

Stack-pointer-operations

Operations to manipulate stack pointers.

Definitions and Theorems

Function: read-*sp$inline

(defun read-*sp$inline (proc-mode x86)
 (declare (xargs :stobjs (x86)))
 (declare (type (integer 0 4) proc-mode))
 (b* ((*sp (the (signed-byte 64) (rgfi 4 x86))))
  (case proc-mode
   (0 *sp)
   (1
     (b*
      (((the (unsigned-byte 16) ss-attr)
        (seg-hidden-attri 2 x86))
       (ss.b (data-segment-descriptor-attributesbits->d/b ss-attr)))
      (if (= ss.b 1) (n32 *sp) (n16 *sp))))
   (otherwise 0))))

Theorem: i64p-of-read-*sp

(defthm i64p-of-read-*sp
  (implies (x86p x86)
           (b* ((*sp (read-*sp$inline proc-mode x86)))
             (i64p *sp)))
  :rule-classes :rewrite)

Theorem: read-*sp-is-i64p

(defthm read-*sp-is-i64p
 (implies (x86p x86)
          (signed-byte-p 64 (read-*sp proc-mode x86)))
 :rule-classes
 (:rewrite
  (:type-prescription
      :corollary (implies (x86p x86)
                          (integerp (read-*sp proc-mode x86)))
      :hints (("Goal" :in-theory '(signed-byte-p integer-range-p))))
  (:linear
    :corollary (implies (x86p x86)
                        (and (<= -9223372036854775808
                                 (read-*sp proc-mode x86))
                             (< (read-*sp proc-mode x86)
                                9223372036854775808)))
    :hints
    (("Goal"
          :in-theory '(signed-byte-p integer-range-p (:e expt)))))))

Theorem: read-*sp-when-64-bit-modep

(defthm read-*sp-when-64-bit-modep
  (equal (read-*sp 0 x86)
         (rgfi *rsp* x86)))

Theorem: read-*sp-when-not-64-bit-modep

(defthm read-*sp-when-not-64-bit-modep
 (implies (not (equal proc-mode 0))
          (unsigned-byte-p 32 (read-*sp proc-mode x86)))
 :rule-classes
 (:rewrite
  (:type-prescription
      :corollary (implies (not (equal proc-mode 0))
                          (natp (read-*sp proc-mode x86)))
      :hints
      (("Goal" :in-theory '(unsigned-byte-p integer-range-p natp))))
  (:linear
   :corollary (implies (not (equal proc-mode 0))
                       (and (<= 0 (read-*sp proc-mode x86))
                            (< (read-*sp proc-mode x86)
                               4294967296)))
   :hints
   (("Goal"
        :in-theory '(unsigned-byte-p integer-range-p (:e expt)))))))

Function: add-to-*sp$inline

(defun add-to-*sp$inline (proc-mode *sp delta x86)
 (declare (xargs :stobjs (x86)))
 (declare (type (integer 0 4) proc-mode)
          (type (signed-byte 64) *sp)
          (type (signed-byte 64) delta))
 (b* ((*sp+delta (the (signed-byte 65) (+ *sp delta))))
  (case proc-mode
   (0 (let ((*sp+delta (i64 *sp+delta)))
        (if (mbe :logic (canonical-address-p *sp+delta)
                 :exec (and (<= -140737488355328 *sp+delta)
                            (< *sp+delta 140737488355328)))
            (mv nil *sp+delta)
          (mv (list :non-canonical-stack-address *sp+delta)
              0))))
   (1
     (b*
       (((the (unsigned-byte 32) ss.limit)
         (seg-hidden-limiti 2 x86))
        ((the (unsigned-byte 16) ss-attr)
         (seg-hidden-attri 2 x86))
        (ss.b (data-segment-descriptor-attributesbits->d/b ss-attr))
        (ss.e (data-segment-descriptor-attributesbits->e ss-attr))
        (ss-lower (if (= ss.e 1) (1+ ss.limit) 0))
        (ss-upper (if (= ss.e 1)
                      (if (= ss.b 1) 4294967295 65535)
                    ss.limit))
        (*sp+delta (if (= ss.b 1)
                       (n32 *sp+delta)
                     (n16 *sp+delta)))
        ((unless (and (<= ss-lower *sp+delta)
                      (<= *sp+delta ss-upper)))
         (mv (list :out-of-segment-stack-address
                   *sp+delta ss-lower ss-upper)
             0)))
       (mv nil *sp+delta)))
   (otherwise (mv (list :unimplemented-proc-mode proc-mode)
                  0)))))

Theorem: i64p-of-add-to-*sp.*sp+delta

(defthm i64p-of-add-to-*sp.*sp+delta
  (b* (((mv ?flg ?*sp+delta)
        (add-to-*sp$inline proc-mode *sp delta x86)))
    (i64p *sp+delta))
  :rule-classes :rewrite)

Theorem: add-to-*sp-is-i64p

(defthm add-to-*sp-is-i64p
 (signed-byte-p 48
                (mv-nth 1 (add-to-*sp proc-mode *sp delta x86)))
 :rule-classes
 (:rewrite
  (:type-prescription
      :corollary
      (integerp (mv-nth 1 (add-to-*sp proc-mode *sp delta x86)))
      :hints (("Goal" :in-theory '(signed-byte-p integer-range-p))))
  (:linear
    :corollary
    (and (<= -140737488355328
             (mv-nth 1 (add-to-*sp proc-mode *sp delta x86)))
         (< (mv-nth 1 (add-to-*sp proc-mode *sp delta x86))
            140737488355328))
    :hints
    (("Goal"
          :in-theory '(signed-byte-p integer-range-p (:e expt)))))))

Theorem: mv-nth-0-of-add-to-*sp-when-64-bit-modep

(defthm mv-nth-0-of-add-to-*sp-when-64-bit-modep
 (equal (mv-nth 0 (add-to-*sp 0 *sp delta x86))
        (if (canonical-address-p (i64 (+ *sp delta)))
            nil
          (list :non-canonical-stack-address (i64 (+ *sp delta))))))

Theorem: mv-nth-1-of-add-to-*sp-when-64-bit-modep

(defthm mv-nth-1-of-add-to-*sp-when-64-bit-modep
  (equal (mv-nth 1 (add-to-*sp 0 *sp delta x86))
         (if (canonical-address-p (i64 (+ *sp delta)))
             (i64 (+ *sp delta))
           0)))

Theorem: mv-nth-1-of-add-to-*sp-when-compatibility-modep

(defthm mv-nth-1-of-add-to-*sp-when-compatibility-modep
 (implies
    (and (not (equal proc-mode 0))
         (integerp (+ *sp delta))
         (not (mv-nth 0
                      (add-to-*sp proc-mode *sp delta x86))))
    (unsigned-byte-p 32
                     (mv-nth 1
                             (add-to-*sp proc-mode *sp delta x86))))
 :rule-classes
 (:rewrite
  (:type-prescription
      :corollary
      (implies
           (and (not (equal proc-mode 0))
                (integerp (+ *sp delta))
                (not (mv-nth 0
                             (add-to-*sp proc-mode *sp delta x86))))
           (natp (mv-nth 1
                         (add-to-*sp proc-mode *sp delta x86))))
      :hints
      (("Goal" :in-theory '(unsigned-byte-p integer-range-p natp))))
  (:linear
   :corollary
   (implies
        (and (not (equal proc-mode 0))
             (integerp (+ *sp delta))
             (not (mv-nth 0
                          (add-to-*sp proc-mode *sp delta x86))))
        (and (<= 0
                 (mv-nth 1 (add-to-*sp proc-mode *sp delta x86)))
             (< (mv-nth 1 (add-to-*sp proc-mode *sp delta x86))
                4294967296)))
   :hints
   (("Goal"
        :in-theory '(unsigned-byte-p integer-range-p (:e expt)))))))

Function: write-*sp$inline

(defun write-*sp$inline (proc-mode *sp x86)
 (declare (xargs :stobjs (x86)))
 (declare (type (integer 0 4) proc-mode)
          (type (signed-byte 64) *sp))
 (declare (xargs :guard
                 (if (equal proc-mode 0)
                     t
                   (unsigned-byte-p 32 *sp))))
 (case proc-mode
  (0 (!rgfi 4 *sp x86))
  (1
    (b*
      (((the (unsigned-byte 16) ss-attr)
        (seg-hidden-attri 2 x86))
       (ss.b (data-segment-descriptor-attributesbits->d/b ss-attr)))
      (if (= ss.b 1)
          (mbe :logic (!rgfi 4 (n32 *sp) x86)
               :exec (!rgfi 4 (the (unsigned-byte 32) *sp)
                            x86))
        (b* (((the (signed-byte 64) rsp)
              (rgfi 4 x86))
             ((the (signed-byte 64) rsp-new)
              (mbe :logic (part-install (n16 *sp)
                                        rsp
                                        :low 0
                                        :width 16)
                   :exec (logior (logand -65536 rsp)
                                 (logand 65535 *sp)))))
          (!rgfi 4 rsp-new x86)))))
  (otherwise x86)))

Theorem: x86p-of-write-*sp

(defthm x86p-of-write-*sp
  (implies (x86p x86)
           (b* ((x86-new (write-*sp$inline proc-mode *sp x86)))
             (x86p x86-new)))
  :rule-classes :rewrite)

Theorem: write-*sp-when-64-bit-modep

(defthm write-*sp-when-64-bit-modep
  (equal (write-*sp 0 *sp x86)
         (!rgfi 4 *sp x86)))

Subtopics

Add-to-*sp
Add a specified amount to a stack pointer.
Write-*sp
Write a stack pointer into the register RSP, ESP, or SP.
Read-*sp
Read the stack pointer from the register RSP, ESP, or SP.