• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
      • Gl
      • Esim
      • Vl2014
      • Sv
      • Fgl
      • Vwsim
      • Vl
      • 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
            • Rme32
            • Rime32
            • Gen-read-function
            • Rme256
            • Rme128
            • Rime64
            • Rime16
            • Rme80
            • Rme64
            • Rme48
            • Rme16
            • Gen-write-function
            • Rme-size
            • Rme08
            • Rime08
            • Rime-size
            • Wme-size
            • Wime-size
            • Wme32
              • Wime32
              • Wme80
              • Wme64
              • Wme48
              • Wme256
              • Wme16
              • Wme128
              • Wime64
              • Wime16
              • Address-aligned-p
              • Wme08
              • Wime08
            • App-view
            • X86-decoder
            • Physical-memory
            • Decoding-and-spec-utils
            • 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
        • Svl
        • Rtl
      • Software-verification
      • Math
      • Testing-utilities
    • Top-level-memory

    Wme32

    Write an unsigned 32-bit value to memory via an effective address.

    Signature
    (wme32 proc-mode 
           eff-addr seg-reg val check-alignment? 
           x86 &key (mem-ptr? 'nil)) 
     
      → 
    (mv flg x86-new)
    Arguments
    check-alignment? — Guard (booleanp check-alignment?).
    mem-ptr? — Guard (booleanp mem-ptr?).
    Returns
    x86-new — Type (x86p x86-new), given (x86p x86).

    The effective address eff-addr is translated to a canonical linear address. If this translation is successful and no other error occurs (like alignment errors), then wml32 is called.

    Prior to the effective address translation, we check whether write access is allowed. In 32-bit mode, write access is allowed in data segments (DS, ES, FS, GS, and SS) if the W bit in the segment descriptor is 1; write access is disallowed in code segments (this is not explicitly mentioned in Intel manual, May'18, Volume 3, Section 3.4.5.1, but it seems reasonable). In 64-bit mode, the W bit is ignored (see Atmel manual, Dec'17, Volume 2, Section 4.8.1); by analogy, we allow write access to the code segment as well. These checks may be slightly optimized using the invariant that SS.W must be 1 when SS is loaded.

    Definitions and Theorems

    Function: wme32$inline

    (defun wme32$inline (proc-mode eff-addr seg-reg
                                   val check-alignment? x86 mem-ptr?)
     (declare (xargs :stobjs (x86)))
     (declare (type (integer 0 4) proc-mode)
              (type (signed-byte 64) eff-addr)
              (type (integer 0 5) seg-reg)
              (type (unsigned-byte 32) val))
     (declare (xargs :guard (and (booleanp check-alignment?)
                                 (booleanp mem-ptr?))))
     (b*
      (((when
         (and
          (/= proc-mode 0)
          (or (= seg-reg 1)
              (b* ((attr (loghead 16 (seg-hidden-attri seg-reg x86)))
                   (w (data-segment-descriptor-attributesbits->w attr)))
                (= w 0)))))
        (mv (list :non-writable-segment eff-addr seg-reg)
            x86))
       ((mv flg lin-addr)
        (ea-to-la proc-mode eff-addr seg-reg 4 x86))
       ((when flg) (mv flg x86))
       ((unless (or (not check-alignment?)
                    (address-aligned-p lin-addr 4 mem-ptr?)))
        (mv (list :unaligned-linear-address lin-addr)
            x86)))
      (wml32 lin-addr val x86)))

    Theorem: x86p-of-wme32.x86-new

    (defthm x86p-of-wme32.x86-new
      (implies (x86p x86)
               (b* (((mv ?flg ?x86-new)
                     (wme32$inline proc-mode eff-addr seg-reg
                                   val check-alignment? x86 mem-ptr?)))
                 (x86p x86-new)))
      :rule-classes :rewrite)

    Theorem: wme32-when-64-bit-modep-and-not-fs/gs

    (defthm wme32-when-64-bit-modep-and-not-fs/gs
      (implies (and (not (equal seg-reg 4))
                    (not (equal seg-reg 5))
                    (canonical-address-p eff-addr)
                    (or (not check-alignment?)
                        (address-aligned-p eff-addr 4 mem-ptr?)))
               (equal (wme32 0 eff-addr
                             seg-reg val check-alignment? x86
                             :mem-ptr? mem-ptr?)
                      (wml32 eff-addr val x86))))

    Theorem: wme32-unaligned-when-64-bit-modep-and-not-fs/gs

    (defthm wme32-unaligned-when-64-bit-modep-and-not-fs/gs
      (implies (and (not (equal seg-reg 4))
                    (not (equal seg-reg 5))
                    (not (or (not check-alignment?)
                             (address-aligned-p eff-addr 4 mem-ptr?)))
                    (canonical-address-p eff-addr))
               (equal (wme32 0 eff-addr
                             seg-reg val check-alignment? x86
                             :mem-ptr? mem-ptr?)
                      (list (list :unaligned-linear-address eff-addr)
                            x86))))

    Theorem: wme32-when-64-bit-modep-and-fs/gs

    (defthm wme32-when-64-bit-modep-and-fs/gs
     (implies
      (or (equal seg-reg 4) (equal seg-reg 5))
      (equal (wme32 0 eff-addr
                    seg-reg val check-alignment? x86
                    :mem-ptr? mem-ptr?)
             (b* (((mv flg lin-addr)
                   (b* (((mv base & &)
                         (segment-base-and-bounds 0 seg-reg x86))
                        (lin-addr (i64 (+ base (n64 eff-addr)))))
                     (if (canonical-address-p lin-addr)
                         (mv nil lin-addr)
                       (mv (list :non-canonical-address lin-addr)
                           0))))
                  ((when flg) (mv flg x86))
                  ((unless (or (not check-alignment?)
                               (address-aligned-p lin-addr 4 mem-ptr?)))
                   (mv (list :unaligned-linear-address lin-addr)
                       x86)))
               (wml32 lin-addr val x86)))))