number printing routine, fix integer division rounding bug

This commit is contained in:
Jeremy Penner 2019-11-16 15:55:39 -05:00
parent a3fb0b95df
commit c12c67b556
9 changed files with 329 additions and 19 deletions

BIN
asm.img

Binary file not shown.

24
asm.qf
View file

@ -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

2
clean.bat Executable file
View file

@ -0,0 +1,2 @@
del asm.img
build

3
cleanall.bat Executable file
View file

@ -0,0 +1,3 @@
del *.img
build

34
in.asm
View file

@ -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

BIN
out.com

Binary file not shown.

57
qf.asm Executable file
View file

@ -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

4
qf.bas
View file

@ -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

224
trace.txt
View file

@ -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