fix(interpreter): invalid operator precendece for padding byte

This commit is contained in:
2025-07-05 00:04:35 +09:00
parent 89634e50c4
commit aba85c9a48

View File

@@ -52,28 +52,30 @@ impl Computer {
fn init_stack(&mut self) -> Result<(), InterpreterError> { fn init_stack(&mut self) -> Result<(), InterpreterError> {
let mut args = Args::parse(); let mut args = Args::parse();
// set executable name as argv[0]
let path = &args.path.unwrap(); let path = &args.path.unwrap();
let filename = Path::new(path).file_name().unwrap().to_str().unwrap(); let filename = Path::new(path).file_name().unwrap().to_str().unwrap();
// add the rest of the arguements argv[1], ...
let mut argv = Vec::from([filename.to_string()]); let mut argv = Vec::from([filename.to_string()]);
argv.append(&mut args.argv); argv.append(&mut args.argv);
let argc = argv.len();
let mut argv_ptrs = Vec::new();
// set default env
let envs = Vec::from(["PATH=/usr:/usr/bin".to_string()]); let envs = Vec::from(["PATH=/usr:/usr/bin".to_string()]);
// Padding // alignment byte
let total_len_argv = argv.iter().map(|i| i.len()).sum::<usize>(); let total_len_env = envs.iter().map(|i| i.len()).sum::<usize>();
let total_len_env = 1 // padding for env string null delimeter let total_len_argv = 1 // padding for argv string null delimeter
+ envs.iter().map(|i| i.len() // len of single env entry + argv.iter().map(|i| i.len() // len of single argv entry
+ 1 // padding for each env null delimeter + 1 // padding for each null delimeter
).sum::<usize>(); ).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."); 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 string
self.push_stack(ImmediateOperand::Byte(0))?; // env null delimeter 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"); log::debug!("Adding env {env} to stack");
@@ -84,7 +86,8 @@ impl Computer {
} }
let env_head = self.regs.sp; let env_head = self.regs.sp;
// Write argv // write 0-terminated argv's
let mut argv_ptrs = Vec::new();
for arg in argv.iter() { for arg in argv.iter() {
log::debug!("Adding arg {arg} to stack"); log::debug!("Adding arg {arg} to stack");
self.push_stack(ImmediateOperand::Byte(0))?; self.push_stack(ImmediateOperand::Byte(0))?;
@@ -95,23 +98,25 @@ impl Computer {
argv_ptrs.push(self.regs.sp); argv_ptrs.push(self.regs.sp);
} }
// padding
self.push_stack(ImmediateOperand::Word(0))?; self.push_stack(ImmediateOperand::Word(0))?;
// add env ptr // add ptr to env string
log::debug!("Pushing env ptr"); log::debug!("Pushing env ptr");
self.push_stack(env_head.into())?; self.push_stack(ImmediateOperand::Word(env_head))?;
// padding
self.push_stack(ImmediateOperand::Word(0))?; self.push_stack(ImmediateOperand::Word(0))?;
// add argv ptrs // add ptrs to each arguments
for addr in argv_ptrs { for addr in argv_ptrs {
log::debug!("Pushing argv ptr {addr:#04x}"); log::debug!("Pushing argv ptr {addr:#04x}");
self.push_stack(addr.into())?; self.push_stack(ImmediateOperand::Word(addr))?;
} }
// add argc // add argc
log::debug!("Pushing argc"); log::debug!("Pushing argc");
self.push_stack(ImmediateOperand::Word(argc as Word))?; self.push_stack(ImmediateOperand::Word(argv.len() as Word))?;
Ok(()) Ok(())
} }
@@ -236,6 +241,7 @@ impl Computer {
) -> Result<(), InterpreterError> { ) -> Result<(), InterpreterError> {
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs - rhs; let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs - rhs;
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, lhs, rhs| { let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, lhs, rhs| {
// log::info!("{:?} {:?} {}", lhs, rhs, lhs < rhs);
flags.cf = lhs < rhs; flags.cf = lhs < rhs;
flags.of = lhs.msb() != rhs.msb() && lhs.msb() != result.msb(); flags.of = lhs.msb() != rhs.msb() && lhs.msb() != result.msb();
flags.zf = result.zero(); flags.zf = result.zero();