diff --git a/src/assembly.pest b/src/assembly.pest index 082f0a7..ec8a0f7 100644 --- a/src/assembly.pest +++ b/src/assembly.pest @@ -4,7 +4,7 @@ COMMENT = _{ ";" ~ (!NEWLINE ~ ANY)* } program = { SOI ~ (instruction ~ (NEWLINE | COMMENT)*)* ~ EOI } -instruction = _{ mov | add | sub | mul | div | jmp | cmp | label | org } +instruction = _{ mov | add | sub | mul | div | jmp | cmp | label | org | inc } mov = { "mov" ~ operand ~ "," ~ operand } add = { "add" ~ operand ~ "," ~ operand } sub = { "sub" ~ operand ~ "," ~ operand } @@ -13,10 +13,11 @@ div = { "div" ~ operand } jmp = { "jmp" ~ name } cmp = { "cmp" ~ operand ~ "," ~ operand } org = { "org" ~ imm } +inc = { "inc" ~ operand } name = { ASCII_ALPHANUMERIC+ } label = { ASCII_ALPHANUMERIC+ ~ ":" } -operand = _{ register | imm | mem } +operand = _{ register | imm | mem | indirect } /// Operand should be parsed into reg8/reg16/imm. /// So register and number are defined as the silent rule. @@ -34,4 +35,8 @@ mem8 = { "byte ptr" ~ memx } mem16 = { "word ptr" ~ memx | memx } memx = @{ "[" ~ imm ~ "]" } +indirect = { "[" ~ base* ~ index* ~ "]" } +base = { "bx" | "bp" } +index = { "si" | "di" } + hex = @{ ASCII_DIGIT | "a" | "b" | "c" | "d" | "e" | "f" } diff --git a/src/inc.rs b/src/inc.rs new file mode 100644 index 0000000..56d2579 --- /dev/null +++ b/src/inc.rs @@ -0,0 +1,72 @@ +use crate::memory::Memory; +use crate::parser::{imm_to_num, Rule}; +use crate::{cpucontext::CpuContext, define_handler_one}; +use paste::paste; +use pest::iterators::Pair; + +/* +inc +1. 1-byte form: inc 16-bit registers +Opcode bit 7-3: 01000 +bit 2-0: register table + +2. 2-byte form: inc 8-bit registers (If operand is 8-bit reg, mod is always 11 and bit 5-3 is 000) +1-byte Opcode bit 7-1: opcode 1111111 +1-byte W-bit 0: 0-operand is 8-bit +2-byte mod-bit 7-6: 11 +2-byte Opcode bit 5-3: 000 +2-byte bit 2-0: register table + +3. 3-byte form: inc memory location +1-byte Opcode bit 7-1: 1111111 +1-byte W bit 0: 0-8bit, 1-16bit +2-byte mod-bit 7-6: 01-8bit contents of next byte of instruction sign extended to 16 bits +2-byte Opcode 5-3: 000 +2-byte r/m 2-0: (base and index register) +3-byte Displacement 7-0 + +3. 4-byte form: inc memory location +1-byte Opcode bit 7-1: 1111111 +1-byte W bit 0: 0-8bit, 1-16bit +2-byte mod-bit 7-6 + * 10-indirect addressing mode, use base register and 16bit displacement of next two byte of instruction + (next byte->least significant eight bits, byte after that->most sig bits) + * 00-direct addressing mode, no use base register, only use 16bit displacement +2-byte Opcode 5-3: 000 +2-byte r/m 2-0: (base and index register) +3-byte Displacement 7-0 +4-byte Displacement 15-8 + +register table +000 AX AL +001 CX CL +010 DX DL +011 BX BL +100 SP AH +101 BP CH +110 SI DH +111 DI BH + +r/m field | Base register | Index Register +000 | BX | SI +001 | BX | DI +010 | BP | SI +011 | BP | DI +100 | none | SI +101 | none | DI +110 | BP | none +111 | BX | none + +*/ + +//fn assemble_inc() + +define_handler_one!(inc, first, cpu, memory, { + match first.as_rule() { + Rule::reg16 => { + let v = cpu.get_register(first.as_str()).unwrap(); + cpu.set_register(first.as_str(), v + 1).unwrap(); + } + _ => println!("Not supported operand for org:{:?}", first), + } +}); diff --git a/src/main.rs b/src/main.rs index b6c2c14..9e28536 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod add; mod common; mod cpucontext; +mod inc; mod memory; mod mov; mod org; @@ -48,6 +49,9 @@ impl Hardware8086 { parser::Rule::add => { caller_two!(add, self.cpu, self.memory, instruction); } + parser::Rule::inc => { + caller_one!(inc, self.cpu, self.memory, instruction); + } _ => println!("NOT implemented yet:{}", line), } println!("After instruction: {:?}", self.cpu); diff --git a/src/parser.rs b/src/parser.rs index f5f7abb..fbc2614 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -267,4 +267,13 @@ mod tests { assert_eq!(Err("Invalid hex number".to_owned()), _imm_to_num("0xghi")); } + + #[test] + fn test_parser_indirect_addressing() { + // todo: add test for indirect addressing mode + // inc [bx + si] + // inc [bp + di] + // inc [si] + // ind [di] + } }