ft: impl ret

This commit is contained in:
2025-06-17 12:02:08 +09:00
parent 7f4d79d840
commit 18cc460d40
2 changed files with 30 additions and 32 deletions

View File

@@ -1,6 +1,6 @@
use core::fmt; use core::fmt;
use crate::operands::{ImmediateOperand, MemoryIndex, ModRmTarget}; use crate::operands::{ImmediateOperand, ModRmTarget, Word};
use super::{flags::Flags, interpreter::InterpreterError, memory::Memory, register::Register}; use super::{flags::Flags, interpreter::InterpreterError, memory::Memory, register::Register};
@@ -11,13 +11,6 @@ pub enum ArithmeticOperand {
ModRmTarget(ModRmTarget), ModRmTarget(ModRmTarget),
} }
/// Wrapper for easier argument passing of polymorph pop operations.
#[derive(Debug, Clone)]
pub enum PopTarget {
Register(crate::register::Register),
MemoryIndex(MemoryIndex),
}
type ArithmeticResult = ImmediateOperand; type ArithmeticResult = ImmediateOperand;
type Lhs = ImmediateOperand; type Lhs = ImmediateOperand;
type Rhs = ImmediateOperand; type Rhs = ImmediateOperand;
@@ -45,19 +38,10 @@ impl Computer {
} }
/// Retrieve value from stack and increment stack pointer. /// Retrieve value from stack and increment stack pointer.
pub fn pop_stack(&mut self, target: PopTarget) -> Result<(), InterpreterError> { pub fn pop_stack(&mut self) -> Result<Word, InterpreterError> {
let word = self.memory.read_raw(self.regs.sp)?; let word = self.memory.read_raw(self.regs.sp)?;
match target {
PopTarget::Register(reg) => self.regs.write(reg, word.into()),
PopTarget::MemoryIndex(mem_idx) => self
.memory
.write_raw(Memory::calc_memidx(&self.regs, mem_idx).into(), word.into())?,
}
self.regs.pop()?; self.regs.pop()?;
Ok(word)
Ok(())
} }
/// Perform binary `dest` = `dest` + `src`. Sets flags. /// Perform binary `dest` = `dest` + `src`. Sets flags.
@@ -163,7 +147,9 @@ impl Computer {
} }
ArithmeticOperand::ModRmTarget(mod_rm_target) => { ArithmeticOperand::ModRmTarget(mod_rm_target) => {
ArithmeticOperand::Immediate(match mod_rm_target { ArithmeticOperand::Immediate(match mod_rm_target {
ModRmTarget::Memory(idx) => self.memory.read(&self.regs, idx) + cf, ModRmTarget::Memory(idx) => {
(self.memory.read(&self.regs, idx) + cf as u16).into()
}
ModRmTarget::Register(reg) => self.regs.read(reg) + cf, ModRmTarget::Register(reg) => self.regs.read(reg) + cf,
}) })
} }
@@ -189,7 +175,9 @@ impl Computer {
} }
ArithmeticOperand::ModRmTarget(mod_rm_target) => { ArithmeticOperand::ModRmTarget(mod_rm_target) => {
ArithmeticOperand::Immediate(match mod_rm_target { ArithmeticOperand::Immediate(match mod_rm_target {
ModRmTarget::Memory(idx) => self.memory.read(&self.regs, idx) + cf, ModRmTarget::Memory(idx) => {
(self.memory.read(&self.regs, idx) + cf as u16).into()
}
ModRmTarget::Register(reg) => self.regs.read(reg) + cf, ModRmTarget::Register(reg) => self.regs.read(reg) + cf,
}) })
} }
@@ -243,7 +231,7 @@ impl Computer {
/// Read an [`ImmediateOperand`] from [`Self::memory`] or [`Self::regs`]. /// Read an [`ImmediateOperand`] from [`Self::memory`] or [`Self::regs`].
pub fn read_modrm(&self, target: ModRmTarget) -> ImmediateOperand { pub fn read_modrm(&self, target: ModRmTarget) -> ImmediateOperand {
match target { match target {
ModRmTarget::Memory(idx) => self.memory.read(&self.regs, idx), ModRmTarget::Memory(idx) => self.memory.read(&self.regs, idx).into(),
ModRmTarget::Register(reg) => self.regs.read(reg), ModRmTarget::Register(reg) => self.regs.read(reg),
} }
} }
@@ -265,10 +253,6 @@ mod tests {
let mut c = Computer::new(); let mut c = Computer::new();
let val = ImmediateOperand::Word(0x1234); let val = ImmediateOperand::Word(0x1234);
c.push_stack(val).unwrap(); c.push_stack(val).unwrap();
assert_eq!(val, c.pop_stack().unwrap().into())
let target = PopTarget::Register(crate::register::Register::AX);
c.pop_stack(target).unwrap();
assert_eq!(val, c.regs.read(crate::register::Register::AX))
} }
} }

View File

@@ -1,9 +1,9 @@
use core::fmt; use core::fmt;
use std::{env::current_dir, fmt::Debug, process::exit}; use std::{fmt::Debug, process::exit};
use crate::{ use crate::{
instructions::{Instruction, Mnemonic}, instructions::{Instruction, Mnemonic},
interpreter::{computer::PopTarget, interrupt::Mess1, memory::Memory}, interpreter::{interrupt::Mess1, memory::Memory},
operands::{Byte, ImmediateOperand, ModRmTarget, Word}, operands::{Byte, ImmediateOperand, ModRmTarget, Word},
}; };
@@ -114,8 +114,16 @@ impl Interpreter {
/* /*
* POP * POP
*/ */
Mnemonic::POP_R(reg) => self.computer.pop_stack(PopTarget::Register(reg))?, Mnemonic::POP_R(reg) => {
Mnemonic::POP_M(idx) => self.computer.pop_stack(PopTarget::MemoryIndex(idx))?, let val = self.computer.pop_stack()?.into();
self.computer.regs.write(reg, val);
}
Mnemonic::POP_M(idx) => {
let val = self.computer.pop_stack()?.into();
self.computer
.memory
.write_raw(Memory::calc_memidx(&self.computer.regs, idx).into(), val)?
}
Mnemonic::POP_S(_) => todo!(), Mnemonic::POP_S(_) => todo!(),
/* /*
@@ -508,7 +516,9 @@ impl Interpreter {
*/ */
Mnemonic::LEA(target, reg) => { Mnemonic::LEA(target, reg) => {
let val = match target { let val = match target {
ModRmTarget::Memory(idx) => Memory::calc_memidx(&self.computer.regs, idx), ModRmTarget::Memory(idx) => {
Memory::calc_memidx(&self.computer.regs, idx).into()
}
ModRmTarget::Register(reg) => self.computer.regs.read(reg), ModRmTarget::Register(reg) => self.computer.regs.read(reg),
}; };
self.computer.regs.write(reg, val); self.computer.regs.write(reg, val);
@@ -549,6 +559,10 @@ impl Interpreter {
/* /*
* RET * RET
*/ */
Mnemonic::RET => {
let offset = self.computer.pop_stack()?;
Self::ip_jump(&self.instructions, &mut ip, offset as usize);
}
/* /*
* Load ES/DS Register * Load ES/DS Register