fix(interpreter): fix stack setup

This commit is contained in:
2025-07-02 17:04:09 +09:00
parent 0a55b5a68b
commit 3ce0a461ca
2 changed files with 26 additions and 26 deletions

View File

@@ -56,47 +56,57 @@ impl Computer {
let mut argv_ptrs = Vec::new(); let mut argv_ptrs = Vec::new();
let envs = Vec::from(["PATH=/usr:/usr/bin".to_string()]); let envs = Vec::from(["PATH=/usr:/usr/bin".to_string()]);
let mut env_ptrs = Vec::new();
// Padding // Padding
let total_len_argv: usize = argv.iter().map(|i| i.len()).sum(); let total_len_argv = argv.iter().map(|i| i.len()).sum::<usize>();
let total_len_env: usize = envs.iter().map(|i| i.len()).sum(); let total_len_env = 1 // padding for env string null delimeter
+ envs.iter().map(|i| i.len() // len of single env entry
+ 1 // padding for each env null delimeter
).sum::<usize>();
if total_len_argv + total_len_env % 2 != 0 { if total_len_argv + total_len_env % 2 != 0 {
log::debug!("Pushing aligment byte at top of stack.");
self.push_stack(ImmediateOperand::Byte(0))?; self.push_stack(ImmediateOperand::Byte(0))?;
} }
// Write env // Write env
self.push_stack(ImmediateOperand::Byte(0))?; // env null delimeter
for env in envs.iter() { for env in envs.iter() {
log::debug!("Adding env {env} to stack");
for b in env.chars().rev() { for b in env.chars().rev() {
log::debug!("{}", b);
self.push_stack(ImmediateOperand::Byte(b as u8))?; self.push_stack(ImmediateOperand::Byte(b as u8))?;
} }
env_ptrs.push(self.regs.sp);
} }
let env_head = self.regs.sp;
// Write argv // Write argv
for arg in argv.iter() { for arg in argv.iter() {
// self.push_stack(ImmediateOperand::Byte(0))?; log::debug!("Adding arg {arg} to stack");
self.push_stack(ImmediateOperand::Byte(0))?;
for b in arg.chars().rev() { for b in arg.chars().rev() {
log::debug!("{}", b);
self.push_stack(ImmediateOperand::Byte(b as u8))?; self.push_stack(ImmediateOperand::Byte(b as u8))?;
} }
argv_ptrs.push(self.regs.sp); argv_ptrs.push(self.regs.sp);
} }
// add env ptrs self.push_stack(ImmediateOperand::Word(0))?;
for addr in env_ptrs {
self.push_stack(addr.into())?; // add env ptr
} log::debug!("Pushing env ptr");
self.push_stack(env_head.into())?;
// delimiter
self.push_stack(ImmediateOperand::Word(0))?; self.push_stack(ImmediateOperand::Word(0))?;
// add argv ptrs // add argv ptrs
for addr in argv_ptrs { for addr in argv_ptrs {
log::debug!("Pushing argv ptr {addr:#04x}");
self.push_stack(addr.into())?; self.push_stack(addr.into())?;
} }
// add argc // add argc
log::debug!("Pushing argc");
self.push_stack(ImmediateOperand::Word(argc as Word))?; self.push_stack(ImmediateOperand::Word(argc as Word))?;
Ok(()) Ok(())
@@ -104,7 +114,11 @@ impl Computer {
/// Decrement stack pointer and write `val` onto the stack. /// Decrement stack pointer and write `val` onto the stack.
pub fn push_stack(&mut self, val: ImmediateOperand) -> Result<(), InterpreterError> { pub fn push_stack(&mut self, val: ImmediateOperand) -> Result<(), InterpreterError> {
self.regs.push_sp(); self.regs.sp = self.regs.sp.wrapping_sub(match val {
ImmediateOperand::Byte(_) => 1,
ImmediateOperand::Word(_) => 2,
});
log::debug!("writing at sp: {:#04x}", self.regs.sp);
self.memory.write_raw( self.memory.write_raw(
self.mem_addr( self.mem_addr(
ImmediateOperand::from(self.regs.sp).into(), ImmediateOperand::from(self.regs.sp).into(),
@@ -120,7 +134,7 @@ impl Computer {
ImmediateOperand::from(self.regs.sp).into(), ImmediateOperand::from(self.regs.sp).into(),
&crate::register::SegmentRegister::SS, &crate::register::SegmentRegister::SS,
))?; ))?;
self.regs.pop_sp(); self.regs.sp = self.regs.sp.wrapping_add(2);
Ok(word) Ok(word)
} }

View File

@@ -27,20 +27,6 @@ impl Register {
} }
} }
/// Decrement stack pointer
pub fn push_sp(&mut self) {
log::debug!("SP before push: {:04x}", self.sp);
self.sp = self.sp.wrapping_sub(2);
log::debug!("SP after push: {:04x}", self.sp);
}
/// Increment stack pointer
pub fn pop_sp(&mut self) {
log::debug!("SP before pop: {:04x}", self.sp);
self.sp = self.sp.wrapping_add(2);
log::debug!("SP after pop: {:04x}", self.sp);
}
/// Read value from a [`crate::register::Register`]. /// Read value from a [`crate::register::Register`].
pub fn read(&self, reg: crate::register::Register) -> ImmediateOperand { pub fn read(&self, reg: crate::register::Register) -> ImmediateOperand {
match reg { match reg {