summaryrefslogtreecommitdiffhomepage
path: root/doc/mdk_gstart.texi
blob: 4c8b02507f7cbb20e9a25fdd0a445eaabc088baf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
@c -*-texinfo-*-
@c This is part of the GNU MDK Reference Manual.
@c Copyright (C) 2000, 2001
@c   Free Software Foundation, Inc.
@c See the file mdk.texi for copying conditions.

@node Getting started, mixvm.el, MIX and MIXAL tutorial, Top
@comment  node-name,  next,  previous,  up
@chapter Getting started

In this chapter, you will find a sample code-compile-run-debug session
using the @sc{mdk} utilities. Familiarity with the MIX mythical computer
and its assembly language MIXAL (as described in Knuth's TAOCP) is
assumed; for a compact reminder, see @ref{MIX and MIXAL tutorial}. 

@menu
* Writing a source file::       A sample MIXAL source file.
* Compiling::                   Using @code{mixasm} to compile source
                                files into binary format.
* Running the program::         Running and debugging your program.
@end menu

@node Writing a source file, Compiling, Getting started, Getting started
@comment  node-name,  next,  previous,  up
@section Writing a source file
@cindex MIXAL
@cindex source file

MIXAL programs can be written as ASCII files with your editor of choice.
Here you have the mandatory @emph{hello world} as written in the MIXAL
assembly language:

@example
*                                                        (1)
* hello.mixal: say 'hello world' in MIXAL                (2)
*                                                        (3)
* label ins    operand     comment                       (4)
TERM    EQU    19          the MIX console device number (5)
        ORIG   1000        start address                 (6)
START   OUT    MSG(TERM)   output data at address MSG    (7)
        HLT                halt execution                (8)
MSG     ALF    "MIXAL"                                   (9)
        ALF    " HELL"                                   (10)
        ALF    "O WOR"                                   (11)
        ALF    "LD   "                                   (12)
        END    START       end of the program            (13)
@end example
         
@noindent MIXAL source files should have the extension @file{.mixal}
when used with the @sc{mdk} utilities. As you can see in the above
sample, each line in a MIXAL file can be divided into four fields
separated by an arbitrary amount of whitespace characters (blanks and or
tabs). While Knuth's definition of MIXAL each field must start at a
fixed pre-defined column number, the @sc{mdk} assembler loosens this
requirement and lets you format the file as you see fit. The only
restrictions retained are for comment lines (like 1-4) which must begin
with an asterisk (*) placed at column 1, and for the label field (see
below) which, if present, must also start at column 1. The four fields
in each non-comment line are:

@itemize @minus
@item
an optional label, which either refers to the current memory address (as
@code{START} and @code{MSG} in lines 7 and 9) or a defined symbol
(@code{TERM}) (if present, the label must always start at the first
column in its line, for the first whitespace in the line maks the
beginning of the second field),
@item
an operation mnemonic, which can represent either a MIX instruction
(@code{OUT} and @code{HLT} in lines 6 and 7 above), or an assembly
pseudoinstruction.
@item
an optional operand for the (pseudo)instruction, and
@item
an optional free text comment.
@end itemize

@noindent Lines 9-12 of the @file{hello.mixal} file above also show the
second (and last) difference between Knuth's MIXAL definition and ours:
the operand of the @code{ALF} pseudoinstruction (a word of five
characters) must be quoted with using ""@footnote{In Knuth's definition,
the operand always starts at a fixed column number, and the use of
quotation is therefore unnecessary. As @code{mixasm} releases this
requirement, marking the beginning and end of the @code{ALF} operand
disambiguates the parser's recognition of this operand when it includes
blanks}. 

The workings of this sample program should be straightforward if you are
familiar with MIXAL. See TAOCP vol. 1 for a thorought definition or
@ref{MIX and MIXAL tutorial}, for a quick tutorial.

@node Compiling, Running the program, Writing a source file, Getting started
@comment  node-name,  next,  previous,  up
@section Compiling
@cindex compiling
@cindex binary programs
@cindex virtual machine
@cindex assembler
@cindex @code{mixasm}

A simulator of the MIX computer, called @code{mixvm} (MIX virtual
machine) is included in the @sc{mdk} tools. It is able to run binary
files containing MIX instructions written in their binary
representation. You can translate MIXAL source files into this binary
form using @code{mixasm}, the MIXAL assembler. So, in order to compile
the @file{hello.mixal} file, you can type the following 
command at your shell prompt:

@example
mixasm -g hello @key{RET}
@end example

If the source file contains no errors, this will produce a binary file
called @file{hello.mix} which can be loaded and run by the MIX virtual
machine. The @code{-g} flag tells the assembler to include debug
information in the executable file (for a complete description of all
the compilation options, see @ref{mixasm}.) Now, your are ready to run
your first MIX program, as described in the following section.


@node Running the program,  , Compiling, Getting started
@comment  node-name,  next,  previous,  up
@section Running the program
@cindex @code{mixvm}
@cindex non-interactive mode
@cindex interactive mode

MIX is a mythical computer, so it is no use ordering it from your
favorite hardware provider. @sc{mdk} provides a software simulator of
the computer, though. It is called @code{mixvm}, which stands for
@dfn{MIX virtual machine}. Using it, you can run your MIXAL programs,
after compiling them with @code{mixasm} into binary @file{.mix}
files. @code{mixvm} can be used either in @dfn{interactive} or
@dfn{non-interactive} mode. In the second case, @code{mixvm} will load
your program into memory, execute it (producing any output due to MIXAL
@code{OUT} instructions present in the program), and exit when it
encounters a @code{HLT} instruction. In interactive mode, you will enter
a shell prompt which allows you issuing commands to the running virtual
machine. This commands will permit you loading, running and debugging
programs, as well as inspecting the MIX computer state (register
contents, memory cells contents and so on).

@menu
* Non-interactive mode::        Running your programs non-interactively.
* Interactive mode::            Running programs interactively.
* Debugging::                   Commands for debugging your programs.
@end menu

@node Non-interactive mode, Interactive mode, Running the program, Running the program
@comment  node-name,  next,  previous,  up
@subsection Non-interactive mode
@cindex non-interactive mode

To make @code{mixvm} work in non-interactive mode, use the @code{-r}
flag. Thus, to run our @file{hello.mix} program, simply type

@example
mixvm -r hello @key{RET}
@end example

@noindent at your command prompt, and you will get the following output:

@example
MIXAL HELLO WORLD
** Execution time: 11
@end example

@noindent Since our hello world program uses MIX's device number 19 as
its output device (@pxref{Writing a source file}), the output is
redirected to the shell's standard output. Had you used any other MIX
output devices (disks, drums, line printer, etc.), @code{mixvm} would
have created a file named after the device used (e.g. @file{disk4.dev})
and written its output there@footnote{The device files are stored, by
default, in a directory called @file{.mdk}, which is created in your
home directory the first time @code{mixvm} is run. You can change this
default directory using the command @code{devdir} when running
@code{mixvm} in interactive mode (@pxref{Configuration commands})}. Note
also that the virtual machine reports the execution time of the program,
according to the (virtual) time spent in each of the binary instructions
(@pxref{Execution times}).

Sometimes, you will prefer to store the results of your program in MIX
registers rather than writing them to a device. In such cases,
@code{mixvm}'s @code{-d} flag is your friend: it makes @code{mixvm} to
dump the contents of its registers and flags after executing the loaded
program. For instance, typing the following command at your shell's
prompt

@example
mixvm -d -r hello
@end example

@noindent you will obtain the following output:

@example
MIXAL HELLO WORLD
** Execution time: 11
rA: + 00 00 00 00 00 (0000000000)
rX: + 00 00 00 00 00 (0000000000)
rJ: + 00 00 (0000)
rI1: + 00 00 (0000)     rI2: + 00 00 (0000)     
rI3: + 00 00 (0000)     rI4: + 00 00 (0000)     
rI5: + 00 00 (0000)     rI6: + 00 00 (0000)     
Overflow: F
Cmp: E
@end example

@noindent which, in addition to the program's outputs and execution
time, gives you the contents of the MIX registers and the values of the
overflow toggle and comparison flag (admittedly, rather uninteresting in
our sample).

As you can see, running programs non-interactively has many
limitations. You cannot peek the virtual machine's memory contents, not
to mention stepping through your program's instructions or setting
breakpoints. Enter interactive mode.

@node Interactive mode, Debugging, Non-interactive mode, Running the program
@comment  node-name,  next,  previous,  up
@subsection Interactive mode
@cindex interactive mode

To enter the MIX virtual machine interactive mode, simply type

@example
mixvm @key{RET}
@end example

@noindent at your shell command prompt. This command enters the
@code{mixvm} command shell. You will be presented the following command
prompt:

@example
MIX >
@end example

@noindent The virtual machine is initialised and ready to accept your
commands. The @code{mixvm} command shell uses GNU's readline, so that
you have at your disposal command completion (using @key{TAB}) and
history functionality, as well as other line editing shortcuts common to
all utilities using this library (for a complete description of
readline's line editing usage, see @ref{Command Line
Editing,,,Readline}.)

Usually, the first thing you will want to do is loading a compiled MIX
program into memory. This is acomplished by the @code{load} command,
which takes as an argument the name of the @file{.mix} file to be
loaded. Thus, typing

@example
MIX > load hello @key{RET}
Program loaded. Start address: 3000
MIX >
@end example

@noindent will load @file{hello.mix} into the virtual machine's memory
and set the program counter to the address of the first instruction. You
can obtain the contents of the program counter using the command
@code{pc}:

@example
MIX > pc
Current address: 3000
MIX >
@end example

After loading it, you are ready to run the program, using, as you surely
have guessed, the @code{run} command:

@example
MIX > run
Running ...
MIXAL HELLO WORLD                                                     
... done
Elapsed time: 11 /Total program time: 11 (Total uptime: 11)
MIX > 
@end example

@noindent Note that now the timing statistics are richer. You obtain the
elapsed execution time (i.e., the time spent executing instructions
since the last breakpoint), the total execution time for the program up
to now (which in our case coincides with the elapsed time, since there
were no breakpoints), and the total uptime for the virtual machine (you
can load and run more than one program in the same
session)@footnote{Printing of timing statistics can be disabled using
the command @code{timing} (@pxref{Configuration commands}).}. After
running the program, the program counter will point to the address after
the one containing the @code{HLT} instruction. In our case, asking the
value of the program counter after executing the program will give us

@example
MIX > pc
Current address: 3002
MIX >
@end example

@noindent You can check the contents of a memory cell giving its address
as an argument of the command @code{pmem}, like this

@example
MIX > pmem 3001
3001: + 00 00 00 02 05 (0000000133)
MIX >
@end example

@noindent
and convince yourself that address 3001 contains the binary
representation of the instruction @code{HLT}. An address range of the
form FROM-TO can also be used as the argument of @code{pmem}:

@example
MIX > pmem 3000-3006
3000: + 46 58 00 19 37 (0786957541)
3001: + 00 00 00 02 05 (0000000133)
3002: + 14 09 27 01 13 (0237350989)
3003: + 00 08 05 13 13 (0002118477)
3004: + 16 00 26 16 19 (0268542995)
3005: + 13 04 00 00 00 (0219152384)
3006: + 00 00 00 00 00 (0000000000)
MIX >
@end example

@noindent
In a similar manner, you can look at the contents of the MIX registers
and flags. For instance, to ask for the contents of the A register you
can type

@example
MIX > preg A
rA: + 00 00 00 00 00 (0000000000)
MIX >
@end example

@noindent
Use the comand @code{help} to obtain a list of all available commands,
and @code{help COMMAND} for help on a specific command, e.g.

@example
MIX > help run
run             Run loaded or given MIX code file. Usage: run [FILENAME]
MIX > 
@end example

@noindent
For a complete list of commands available at the MIX propmt,
@xref{mixvm}. In the following subsection, you will find a quick tour
over commands useful for debugging your programs.

@node Debugging,  , Interactive mode, Running the program
@comment  node-name,  next,  previous,  up
@subsection Debugging commands

The interactive mode of @code{mixvm} lets you step by step execution of
programs as well as breakpoint setting. Use @code{next} to step through
the program, running its instructions one by one. To run our
two-instruction @file{hello.mix} sample you can do the following:

@example
MIX > load hello
Program loaded. Start address: 3000
MIX > pc
Current address: 3000
MIX > next
MIXAL HELLO WORLD
Elapsed time: 1 /Total program time: 1 (Total uptime: 1)
MIX > pc
Current address: 3001
MIX > next
End of program reached at address 3002
Elapsed time: 10 /Total program time: 11 (Total uptime: 11)
MIX > pc
Current address: 3002
MIX > next
MIXAL HELLO WORLD
Elapsed time: 1 /Total program time: 1 (Total uptime: 12)
MIX > 
MIX > run
Running ...
... done
Elapsed time: 10 /Total program time: 11 (Total uptime: 22)
MIX > @end example
@noindent
(As an aside, the above sample also shows how the virtual machine
handles cummulative time statistics and automatic program restart).

You can set a breakpoint at a given address using the command
@code{sbpa} (set breakpoint at address). When a breakpoint is set,
@code{run} will stop before executing the instruction at the given
address. Typing @code{run} again will resume program execution. Coming
back to our hello world example, we would have:

@example
MIX > sbpa 3001
Breakpoint set at address 3001
MIX > run
Running ...
MIXAL HELLO WORLD                                                     
... stopped: breakpoint at line 8 (address 3001)
Elapsed time: 1 /Total program time: 1 (Total uptime: 23)
MIX > run
Running ...
... done
Elapsed time: 10 /Total program time: 11 (Total uptime: 33)
MIX >
@end example

@noindent
Note that, since we compiled @file{hello.mixal} with debug info enabled
(the @code{-g} flag of @code{mixasm}), the virtual machine is able to
tell us the line in the source file corresponding to the breakpoint we
are setting. As a matter of fact, you can directly set breakpoints at
source code lines using the command @code{sbp LINE_NO}, e.g.

@example
MIX > sbp 4
Breakpoint set at line 7
MIX > 
@end example

@noindent
@code{sbp} sets the breakpoint at the first meaningful source code line;
thus, in the above example we have requested a breakpoint at a line
which does not correspond to a MIX instruction and the breakpoint is set
at the first line containing a real instruction after the given one. To
unset breakpoints, use @code{cbpa ADDRESS} and @code{cbp LINE_NO}, or
@code{cabp} to remove all currently set breakpoints. 

MIXAL lets you define symbolic constants, either using the @code{EQU}
pseudoinstruction or starting an instruction line with a label (which
assigns to the label the value of the current memory address). Each
MIXAL program has, therefore, an associated symbol table which you can
inspect using the @code{psym} command. For our hello world sample, you
will obtain the following output:

@example
MIX > psym
START:  3000
TERM:  19
MSG:  3002
MIX > 
@end example

Other useful commands for debugging are @code{tracing} (which turns on
tracing of executed intructions) and @code{weval} (which evaluates
w-expressions on the fly). For a complete description of all available
MIX commands, @xref{mixvm}.