diff --git a/asm.img b/asm.img index 74b4308..07964a4 100755 Binary files a/asm.img and b/asm.img differ diff --git a/asm.qf b/asm.qf index 73940c3..6536d11 100755 --- a/asm.qf +++ b/asm.qf @@ -9,6 +9,7 @@ var currop 2 const OP_REG16 3 const OP_SREG 4 const OP_IMM +5 const OP_INDIRECT : op! ( op type ) currop @ >r optypes r@ + ! ops r@ + ! 1 r> + currop ! ; @@ -16,12 +17,15 @@ var currop OP_REG8 mkreg reg8 OP_REG16 mkreg reg16 OP_SREG mkreg sreg +OP_INDIRECT mkreg ireg 0 reg16 ax 0 reg8 al 4 reg8 ah 1 reg16 cx 1 reg8 cl 5 reg8 ch 2 reg16 dx 2 reg8 dl 6 reg8 dh 3 reg16 bx 3 reg8 bl 7 reg8 bh 4 reg16 sp 5 reg16 bp 6 reg16 si 7 reg16 di 0 sreg es 1 sreg cs 2 sreg ss 3 sreg ds +0 ireg [ax] 1 ireg [cx] 2 ireg [dx] 3 ireg [bx] +5 ireg [bp] 6 ireg [si] 7 ireg [di] : # OP_IMM op! ; @@ -32,9 +36,11 @@ var lblfixup var currlbl : mk-lbl-fixpoint here currlbl-head @ , tell , lblfixup @ , currlbl-head ! ; +: tell>addr &h100 + ; + : :> makedo tell , 0 , does> 0 # currlbl ! ; : fixlabel.rel currlbl @ @ tell - &hff & tell 1 - seek outb! ; -: fixlabel.addr currlbl @ @ &h100 + tell 2 - seek outw! ; +: fixlabel.addr currlbl @ @ tell>addr tell 2 - seek outw! ; : fixlabel ( fixtype -- ) if fixlabel.rel else fixlabel.addr then ; : fixpoint.seek ( p -- ) 1 + @ seek ; : fixpoint.fix ( p -- ) 2 + @ fixlabel ; @@ -91,6 +97,14 @@ OP_IMM OP_REG8 :noname &hb0 op1 + outb! op2 outb! ; ' movb impl : modrm ( mod rm reg ) 8 * | swap 64 * | outb! ; 2 inst add OP_REG16 OP_REG16 :noname &h01 outb! &h03 op1 op2 modrm ; ' add impl +OP_IMM OP_REG8 :noname &h80 outb! 3 op1 0 modrm op2 outb! ; ' add impl +2 inst xor +OP_REG16 OP_REG16 :noname &h31 outb! &h03 op1 op2 modrm ; ' xor impl +2 inst cmp +OP_IMM OP_REG16 :noname &h81 outb! 3 op1 0 modrm op2 outw! ; ' cmp impl + +1 inst div +OP_REG16 :noname &hf7 outb! &h03 op1 &h06 modrm ; ' div impl 1 inst push &h06 :+sreg ' push impl @@ -98,8 +112,14 @@ OP_REG16 OP_REG16 :noname &h01 outb! &h03 op1 op2 modrm ; ' add impl 1 inst pop &h07 :+sreg ' pop impl &h58 :+r ' pop impl -1 inst dec +1 inst dec &h48 :+r ' dec impl +1 inst inc +&h40 :+r ' inc impl + +1 inst jmp +OP_INDIRECT :noname &hff outb! 0 op1 4 modrm ; ' jmp impl +OP_REG16 :noname &hff outb! 3 op1 4 modrm ; ' jmp impl : :jumprel here >r 1 LBL_REL | inst :| anondo >r , OP_IMM r> does> @ outb! op1 outb! |; execute diff --git a/clean.bat b/clean.bat new file mode 100755 index 0000000..2a462ef --- /dev/null +++ b/clean.bat @@ -0,0 +1,2 @@ +del asm.img +build diff --git a/cleanall.bat b/cleanall.bat new file mode 100755 index 0000000..84543be --- /dev/null +++ b/cleanall.bat @@ -0,0 +1,3 @@ +del *.img +build + diff --git a/in.asm b/in.asm index 2405e47..6fed4e7 100755 --- a/in.asm +++ b/in.asm @@ -1,21 +1,29 @@ cs push \ copy code segment to data segment ds pop - cx 11 # mov + ax 0 # mov +\ print number +\ in: ax = number +\ clobbers: ax, bx, cx, dx + cx 10 # mov + bx bx xor -:> loop - :> msg - dx msg mov - dx cx add - ah 9 # movb +:> moredigits + bx inc + dx dx xor + cx div + dx push + ax 0 # cmp + moredigits jne + +:> moredigits + dx pop + dl 48 # add + ax &h0200 # mov &h21 int - - cx dec - loop jge + bx dec + moredigits jne 0 .EXIT -msg <: - : nl 13 outb! 10 outb! ; - d" Hello World!" nl d" $" - + cx 11 # mov diff --git a/out.com b/out.com index 22597a6..6663b48 100755 Binary files a/out.com and b/out.com differ diff --git a/qf.asm b/qf.asm new file mode 100755 index 0000000..0cec70f --- /dev/null +++ b/qf.asm @@ -0,0 +1,57 @@ + cs push \ copy code segment to data segment + ds pop + +\ print number +\ in: ax = number +\ clobbers: ax, cx, dx + ax 123 # mov + cx 10 # mov +:> moredigits + dx dx xor + cx div + dl 48 # add + ax push + ax &h0200 # mov + &h21 int + ax pop + moredigits jne + + 0 .EXIT + + cx 11 # mov + +\ Register allocation: +\ ax - top of stack value +\ ds:di - pointer above second value in stack +\ ss:sp - return stack pointer +\ ds:bx - instruction pointer +\ dx - current instruction (w) - clobberable + +\ interpreter: indirect threaded +\ dictionary entry layout: +\ next (w) | charcount (b) | name (b+) | codeptr (w) | args... + +:> @next + dx [bx] mov + bx 2 # add + [dx] jmp +: .NEXT @next jmp ; + +: lbl>list mkdoer currlbl @ , 0 currlbl ! + does> @ dup execute dlbl execute <: ; + +:> @latest @latest lbl>list latest! +: outname! + tell 0 outb! + 0 begin in@ dup [ in@ lit ] != while outb! 1 + repeat drop + tell >rot swap seek outb! seek ; +: @mkword latest! outname! ; +: :asm @mkword tell 2 + tell>addr outw! ; + +:asm ; bx pop .NEXT +:> $docolon + bx push + dx bx mov + .NEXT + + diff --git a/qf.bas b/qf.bas index 9e9f199..9c0b5fb 100755 --- a/qf.bas +++ b/qf.bas @@ -39,7 +39,7 @@ COMMON SHARED trace% inline% = -1 interpretcp = -1 -trace% = 10 ' 10 +trace% = 0 ' 10 OPEN "messages.txt" FOR INPUT AS #1 FOR i = 0 TO 31 @@ -325,7 +325,7 @@ SUB execute (op%) CASE O.DIV r = pop l = pop - CALL push(l / r) + CALL push(INT(l / r)) CASE O.BITAND r = pop diff --git a/trace.txt b/trace.txt index bd0f8ee..ff640e5 100755 --- a/trace.txt +++ b/trace.txt @@ -35,6 +35,9 @@ read: OP_SREG read: 4 read: const read: OP_IMM +read: 5 +read: const +read: OP_INDIRECT read: : read: op! read: ( @@ -83,6 +86,9 @@ read: reg16 read: OP_SREG read: mkreg read: sreg +read: OP_INDIRECT +read: mkreg +read: ireg read: 0 read: reg16 read: ax @@ -143,6 +149,27 @@ read: ss read: 3 read: sreg read: ds +read: 0 +read: ireg +read: [ax] +read: 1 +read: ireg +read: [cx] +read: 2 +read: ireg +read: [dx] +read: 3 +read: ireg +read: [bx] +read: 5 +read: ireg +read: [bp] +read: 6 +read: ireg +read: [si] +read: 7 +read: ireg +read: [di] read: : read: # read: OP_IMM @@ -177,6 +204,11 @@ read: currlbl-head read: ! read: ; read: : +read: tell>addr +read: &h100 +read: + +read: ; +read: : read: :> read: makedo read: tell @@ -209,8 +241,7 @@ read: fixlabel.addr read: currlbl read: @ read: @ -read: &h100 -read: + +read: tell>addr read: tell read: 2 read: - @@ -537,6 +568,37 @@ read: ; read: ' read: add read: impl +read: 2 +read: inst +read: xor +read: OP_REG16 +read: OP_REG16 +read: :noname +read: &h31 +read: outb! +read: &h03 +read: op1 +read: op2 +read: modrm +read: ; +read: ' +read: xor +read: impl +read: 1 +read: inst +read: div +read: OP_REG16 +read: :noname +read: &hf7 +read: outb! +read: &h03 +read: op1 +read: &h06 +read: modrm +read: ; +read: ' +read: div +read: impl read: 1 read: inst read: push @@ -571,6 +633,33 @@ read: :+r read: ' read: dec read: impl +read: 1 +read: inst +read: jmp +read: OP_INDIRECT +read: :noname +read: &hff +read: outb! +read: 0 +read: op1 +read: 4 +read: modrm +read: ; +read: ' +read: jmp +read: impl +read: OP_REG16 +read: :noname +read: &hff +read: outb! +read: 3 +read: op1 +read: 4 +read: modrm +read: ; +read: ' +read: jmp +read: impl read: : read: :jumprel read: here @@ -658,6 +747,42 @@ read: push read: \ read: ds read: pop +read: \ +read: \ +read: \ +read: ax +read: 123 +read: # +read: mov +read: cx +read: 10 +read: # +read: mov +read: :> +read: moredigits +read: dx +read: dx +read: xor +read: cx +read: div +read: dl +read: 48 +read: # +read: add +read: ax +read: push +read: ax +read: &h0200 +read: # +read: mov +read: &h21 +read: int +read: ax +read: pop +read: moredigits +read: jne +read: 0 +read: .EXIT read: cx read: 11 read: # @@ -696,3 +821,98 @@ read: ; read: d" read: nl read: d" +read: \ +read: \ +read: \ +read: \ +read: \ +read: \ +read: \ +read: \ +read: \ +read: :> +read: @next +read: dx +read: [bx] +read: mov +read: bx +read: 2 +read: # +read: add +read: [dx] +read: jmp +read: : +read: .NEXT +read: @next +read: jmp +read: ; +read: : +read: lbl>list +read: mkdoer +read: currlbl +read: @ +read: , +read: 0 +read: currlbl +read: ! +read: does> +read: @ +read: dup +read: execute +read: dlbl +read: execute +read: <: +read: ; +read: :> +read: @latest +read: @latest +read: lbl>list +read: latest! +read: : +read: outname! +read: tell +read: 0 +read: outb! +read: 0 +read: begin +read: in@ +read: dup +read: [ +read: in@ +read: lit +read: ] +read: != +read: while +read: outb! +read: 1 +read: + +read: repeat +read: drop +read: tell +read: >rot +read: swap +read: seek +read: outb! +read: seek +read: ; +read: : +read: @mkword +read: latest! +read: outname! +read: ; +read: : +read: :asm +read: @mkword +read: tell +read: 2 +read: + +read: tell>addr +read: outw! +read: ; +read: :asm +read: bx +read: pop +read: .NEXT +read: :> +read: $docolon +read: bx