fix(interpreter): fix stack setup
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user