1 First, we've got some horrible failure in ADD (+) to
2 fix:
3
4 6 6 + .
5 134914672
6
7 Sure enough, I was doing this
8
9 pop byte [eax]
10
11 instead of this
12
13 pop eax
14
15 for reasons involving being very sleepy.
16
17 Is it fixed with the right stack poppin'?
18
19 5 5 + .
20 10
21 33 7 + .
22 40
23
24 Yup! Now continuing on, we've got a bunch of comparison
25 operators - some of them seem downright silly. But Leo
26 Brodie explains in Starting Forth that having all these
27 means smaller word definitions (space being paramount on
28 those original systems) and potentially faster.
29
30 I'll put the answers on the same line to make it much
31 easier to read (and many FORTH systems would have displayed
32 the response on the same line anyway, so this output is
33 super authentic).
34
35 4 4 = . 1
36 5 4 = . 0
37 4 4 <> . 0
38 5 4 <> . 1
39 7 3 < . 0
40 3 7 < . 1
41 7 3 > . 1
42 3 7 > . 0
43 7 3 >= . 1
44 3 3 >= . 1
45 4 3 >= . 1
46 7 3 <= . 0
47 3 3 <= . 1
48 5 0= . 0
49 0 0= . 1
50 5 0<> . 1
51 0 0<> . 0
52 5 0< .. PARSE ERROR: 5 0< ..
53 5 0< . 0
54 -5 0< . 1
55 5 0> . 1
56 -5 0> . 0
57 0 0> . 0
58 5 0>= . 1
59 0 0>= . 1
60 -7 0>= . 0
61 -7 0<= . 1
62 0 0<= . 1
63 7 0<= . 0
64
65 I left in that fat-fingered '..' to break up the monotony.
66 Everyone enjoys a good PARSE ERROR, no?
67 But you can see how these work. The comparisons expect
68 either 1 or 2 numbers on the stack. They leave a 1 for
69 true and 0 for false.
70
71 Next come some bitwise operators:
72
73 1 2 AND . 0
74
75 01 AND 10 = 00
76
77 3 2 AND . 2
78
79 11 AND 10 = 10
80
81 1 2 OR . 3
82
83 01 OR 10 = 11
84
85 1 2 XOR . 3
86
87 01 XOR 10 = 11
88
89 3 2 OR . 3
90
91 11 OR 10 = 11
92
93 3 2 XOR . 1
94
95 11 XOR 10 = 01
96
97 1 INVERT . 65534
98
99 00000000000001 NOT = 111111111111110
100
101 0 INVERT .
102 Program received signal SIGSEGV, Segmentation fault.
103 _FIND.test_word () at nasmjf.asm:532
104 532 mov al, [edx+4] ; al = flags+length field
105 10 INVERT .
106 65525
107 100 INVERT .
108 Program received signal SIGSEGV, Segmentation fault.
109 _FIND.test_word () at nasmjf.asm:532
110 532 mov al, [edx+4] ; al = flags+length field
111
112 Hmmmm... I've run into this before - certain numeric
113 literals sometimes crash the interpreter with a segfault
114 in FIND.test_word. I need to step through that eventually.
115
116 Aha! Got it. Really silly problem as it turns out.
117 I had defined the word_buffer memory space in the
118 .data segment like so:
119
120 word_buffer:
121 db 32 ; 32 bytes of buffer for word names
122
123 But that didn't do what the comment said - instead, it
124 put the single value 32 in a single byte of space!
125
126 So whenever I entered *anything* in the interpreter
127 longer than a handful of characters (not just one because
128 of 4 byte alignment), I was overwriting whatever came
129 next in memory, which happened to be word definitions!
130
131 The correct definition:
132
133 word_buffer:
134 db 32 dup (0) ; 32 bytes of buffer for word names
135
136 actually initializes the memory with 32 bytes all
137 containing the value 0.
138
139 1111 .
140 1111
141 11111111 .
142 11111111
143
144 That would have always crashed before. Now it's fixed.
145
146 Looks like next up are some low-level memory primitives.