Dave's nasmjf Dev Log 13

Created: 2022-07-22

nasmjf home

This is an entry in my developer’s log series written between December 2021 and August 2022 (started project in September). I wrote these as I completed my port of the JONESFORTH assembly language Forth interpreter.

← Previous 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Next →
    Now we can start fleshing out this Forth implementation
    with some basic words. I'll start with the stack manipulation
    words as defined in assembly (for speed) in JonesFORTH:

        ; drop top of stack
        DEFCODE "DROP",4,,DROP
        pop eax
        NEXT

    I'll test each one out as I go. Here's DROP:

65 EMIT
A
65 66 67
DROP EMIT
B
EMIT
A

    Good, it dropped 67 ('c') from the top of the stack.

    And swap:

        ; swap top two elements
        DEFCODE "SWAP",4,,SWAP
        pop eax
        pop ebx
        push eax
        push ebx
        NEXT

    Which is easy to test:

65 66 EMIT EMIT
BA
65 66 SWAP EMIT EMIT
AB

    Finally,

        ; duplicate element on top of stack
        DEFCODE "DUP",3,,DUP
        mov eax, [esp]
        push eax
        NEXT

65 DUP 66 DUP EMIT EMIT EMIT EMIT
BBAA

    Awesome.

    Next night: okay I've ported over OVER, ROT, -ROT,
    2DROP, 2DUP, 2SWAP, and ?DUP. I'll just test them all
    at once and won't bother with the source - they're
    as simple as the above - so it's really easy to read
    their assembly definitions in the source file.

: A 65 ;
A EMIT
A
: B 66 ;
: C 67 ;
: D 68 ;
: e EMIT ;
A B C D e e e e
DCBA
A B C OVER e e e e
BCBA
A B C ROT e e e
ACB
A B C -ROT e e e
BAC
A B C D DROP e e e
CBA
A B C D 2DROP e e
BA
A B C D 2SWAP e e e e
BADC
A B ?DUP e e e
BBA
A B 0 ?DUP e e e

Program received signal SIGSEGV, Segmentation fault.
_FIND.test_word () at nasmjf.asm:532
532         mov al, [edx+4]           ; al = flags+length field
(gdb)

    LOL, well, ?DUP is a little hard to test compared
    to the others. Though a segfault for trying to print
    an ASCII NUL seems weird, and is GDB telling me it
    crashed in FIND? Hmm. I'll have to keep an eye on that.

    The next series of words to define in assembly are
    math operators, which is great. But I think I'm going
    to need to be able to display numbers before that'll
    be any fun to test.

    ...

    Several nights later: Done! Thanks to one of the utility
    routines I wrote as part of the excellent asmtutor.com,
    I was able to slap in a temporary stand-in for the DOT
    word which Jones defines in pure Forth.

    DOT (.) pops and prints the numeric value at the top of
    the stack. At least, I think it's supposed to pop the
    value...well, mine does, for now.

Starting program: /home/dave/nasmjf/nasmjf
Continuing.
1 .
1
11 .
11
111 .
111
1111 .
1111
11111 .

Program received signal SIGSEGV, Segmentation fault.
_FIND.test_word () at nasmjf.asm:532
532         mov al, [edx+4]           ; al = flags+length field

    Works great, but for some reason, accessing edx+4 causes a
    segfault when we try to match a word with a 5-digit number?
    I started stepping throuh it, but I wasn't feeling like
    chasing the rabbit into that particular hole tonight. We've
    got some new math-related words to test!

    1+ and 1- increment and decrement.
    4+ and 4- do the same, but by 4.

5 1+ .
6
5 1- .
4
5 4+ .
9
5 4- .
1

    Then we have + and -.

5 4 + .
134521461

    LOL, what?

5 4 + .
Program received signal SIGSEGV, Segmentation fault.
0x00000004 in ?? ()

    Well, clearly "+" has a bug.

5 4 - .
1

    But "-" looks good. I'm curious about a negative
    value:

4 5 - .
4294967295

    I'll have to check thia answer. Is this -1?

    Moving on, we have multiplication and division:

2 3 * .
6
10 5 /MOD . .
2 0
100 3 /MOD . .
33 1

    Great! Note: I added space beween the quotient and remainder
    for readability. The 'real' DOT in forth prints a space after
    each digit.

    Cool! So we've got math!

    Oh, and we need a satisfying conclusion on the ?DUP operator
    from our stack manipulation words from the beginning of this
    particular log.

    ?DUP duplicates the value on the top of the stack IF it's not
    zero:

1 2 3 ?DUP . . .
332
1 2 0 ?DUP . . .
021

    Yup, that works!

    Looks like I'll find the bug in "+" next. :-)

    Yup, fixed that with the next set of words. See next log.
← Previous 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Next →