summaryrefslogtreecommitdiff
path: root/Userland/DevTools/UserspaceEmulator
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-12-06 17:31:52 +0100
committerAndreas Kling <kling@serenityos.org>2022-12-07 13:18:48 +0100
commit661a940ddda57a89509e00ae8b107d1c28e1dc8c (patch)
tree1edfac07853f3e35a34dd65bd0df68467c94ce7f /Userland/DevTools/UserspaceEmulator
parentbd1f39ebaa42c3e6d570fa3e8818e84135e184c5 (diff)
downloadserenity-661a940ddda57a89509e00ae8b107d1c28e1dc8c.zip
UserspaceEmulator: Implement MOV_seg_RM32 and MOV_seg_RM16
This allows hosted programs to write to segment registers. :^)
Diffstat (limited to 'Userland/DevTools/UserspaceEmulator')
-rw-r--r--Userland/DevTools/UserspaceEmulator/SoftCPU.cpp20
-rw-r--r--Userland/DevTools/UserspaceEmulator/SoftCPU.h2
2 files changed, 20 insertions, 2 deletions
diff --git a/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp b/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp
index f39c6e8d7f..0ee6bb338e 100644
--- a/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp
+++ b/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp
@@ -2153,8 +2153,24 @@ void SoftCPU::MOV_reg8_imm8(const X86::Instruction& insn)
gpr8(insn.reg8()) = shadow_wrap_as_initialized(insn.imm8());
}
-void SoftCPU::MOV_seg_RM16(const X86::Instruction&) { TODO_INSN(); }
-void SoftCPU::MOV_seg_RM32(const X86::Instruction&) { TODO_INSN(); }
+void SoftCPU::write_segment_register(X86::SegmentRegister segment_register, ValueWithShadow<u16> value)
+{
+ // FIXME: Validate the segment selector and raise exception if necessary.
+ // FIXME: Complain if uninitialized data is moved into a segment register.
+ m_segment[to_underlying(segment_register)] = value.value();
+}
+
+void SoftCPU::MOV_seg_RM16(X86::Instruction const& insn)
+{
+ write_segment_register(insn.segment_register(), insn.modrm().read16(*this, insn));
+}
+
+void SoftCPU::MOV_seg_RM32(X86::Instruction const& insn)
+{
+ // NOTE: This instruction performs a 32-bit read but only the bottom 16 bits are used since segment registers are 16-bit.
+ auto value = insn.modrm().read32(*this, insn);
+ write_segment_register(insn.segment_register(), ValueWithShadow<u16>(value.value(), value.shadow_as_value()));
+}
void SoftCPU::MUL_RM16(const X86::Instruction& insn)
{
diff --git a/Userland/DevTools/UserspaceEmulator/SoftCPU.h b/Userland/DevTools/UserspaceEmulator/SoftCPU.h
index 7975343aa9..4e1bc5d3c9 100644
--- a/Userland/DevTools/UserspaceEmulator/SoftCPU.h
+++ b/Userland/DevTools/UserspaceEmulator/SoftCPU.h
@@ -1348,6 +1348,8 @@ private:
void update_code_cache();
+ void write_segment_register(X86::SegmentRegister, ValueWithShadow<u16>);
+
Emulator& m_emulator;
SoftFPU m_fpu;
SoftVPU m_vpu;