diff --git a/src/interpreter/computer.rs b/src/interpreter/computer.rs index f114573..d62ee60 100644 --- a/src/interpreter/computer.rs +++ b/src/interpreter/computer.rs @@ -56,47 +56,57 @@ impl Computer { let mut argv_ptrs = Vec::new(); let envs = Vec::from(["PATH=/usr:/usr/bin".to_string()]); - let mut env_ptrs = Vec::new(); // Padding - let total_len_argv: usize = argv.iter().map(|i| i.len()).sum(); - let total_len_env: usize = envs.iter().map(|i| i.len()).sum(); + let total_len_argv = argv.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::(); if total_len_argv + total_len_env % 2 != 0 { + log::debug!("Pushing aligment byte at top of stack."); self.push_stack(ImmediateOperand::Byte(0))?; } // Write env + self.push_stack(ImmediateOperand::Byte(0))?; // env null delimeter for env in envs.iter() { + log::debug!("Adding env {env} to stack"); for b in env.chars().rev() { + log::debug!("{}", b); self.push_stack(ImmediateOperand::Byte(b as u8))?; } - env_ptrs.push(self.regs.sp); } + let env_head = self.regs.sp; // Write argv 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() { + log::debug!("{}", b); self.push_stack(ImmediateOperand::Byte(b as u8))?; } argv_ptrs.push(self.regs.sp); } - // add env ptrs - for addr in env_ptrs { - self.push_stack(addr.into())?; - } + self.push_stack(ImmediateOperand::Word(0))?; + + // add env ptr + log::debug!("Pushing env ptr"); + self.push_stack(env_head.into())?; - // delimiter self.push_stack(ImmediateOperand::Word(0))?; // add argv ptrs for addr in argv_ptrs { + log::debug!("Pushing argv ptr {addr:#04x}"); self.push_stack(addr.into())?; } // add argc + log::debug!("Pushing argc"); self.push_stack(ImmediateOperand::Word(argc as Word))?; Ok(()) @@ -104,7 +114,11 @@ impl Computer { /// Decrement stack pointer and write `val` onto the stack. 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.mem_addr( ImmediateOperand::from(self.regs.sp).into(), @@ -120,7 +134,7 @@ impl Computer { ImmediateOperand::from(self.regs.sp).into(), &crate::register::SegmentRegister::SS, ))?; - self.regs.pop_sp(); + self.regs.sp = self.regs.sp.wrapping_add(2); Ok(word) } diff --git a/src/interpreter/register.rs b/src/interpreter/register.rs index 675c33b..d00ac40 100644 --- a/src/interpreter/register.rs +++ b/src/interpreter/register.rs @@ -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`]. pub fn read(&self, reg: crate::register::Register) -> ImmediateOperand { match reg {