x86emu/emulator/
mov.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::AlignmentMode;
5use super::Emulator;
6use super::Error;
7use super::InternalError;
8use crate::Cpu;
9use crate::Segment;
10use iced_x86::Instruction;
11use iced_x86::OpKind;
12
13impl<T: Cpu> Emulator<'_, T> {
14    pub(super) async fn mov(&mut self, instr: &Instruction) -> Result<(), InternalError<T::Error>> {
15        let value = self.op_value(instr, 1).await?;
16        self.write_op_0(instr, value).await?;
17        Ok(())
18    }
19
20    pub(super) async fn movsx(
21        &mut self,
22        instr: &Instruction,
23    ) -> Result<(), InternalError<T::Error>> {
24        let value = self.op_value_sign_extend(instr, 1).await?;
25        self.write_op_0(instr, value as u64).await?;
26        Ok(())
27    }
28
29    pub(super) async fn mov_sse(
30        &mut self,
31        instr: &Instruction,
32        alignment: AlignmentMode,
33    ) -> Result<(), InternalError<T::Error>> {
34        let value = match instr.op1_kind() {
35            OpKind::Memory => self.read_memory_op(instr, 1, alignment).await?,
36            OpKind::Register => {
37                let reg = instr.op1_register();
38                assert!(reg.is_xmm());
39                self.cpu.xmm(reg.number())
40            }
41            _ => Err(self.unsupported_instruction(instr))?,
42        };
43
44        match instr.op0_kind() {
45            OpKind::Memory => self.write_memory_op(instr, 0, alignment, value).await?,
46            OpKind::Register => {
47                let reg = instr.op0_register();
48                assert!(reg.is_xmm());
49                let xmm_index = reg.number();
50                self.cpu.set_xmm(xmm_index, value).map_err(|err| {
51                    Error::XmmRegister(xmm_index, super::OperationKind::Write, err)
52                })?
53            }
54            _ => Err(self.unsupported_instruction(instr))?,
55        };
56
57        Ok(())
58    }
59
60    pub(super) async fn movdir64b(
61        &mut self,
62        instr: &Instruction,
63    ) -> Result<(), InternalError<T::Error>> {
64        let mut buffer = [0; 64];
65        let src = self.memory_op_offset(instr, 1);
66        let dst = self.cpu.gp(instr.op0_register().into());
67
68        self.read_memory(
69            instr.memory_segment().into(),
70            src,
71            AlignmentMode::Unaligned,
72            &mut buffer,
73        )
74        .await?;
75
76        self.write_memory(Segment::ES, dst, AlignmentMode::Aligned(64), &buffer)
77            .await?;
78
79        Ok(())
80    }
81}