As already mentioned before the valarrow assembler is compatible with old versions of masm. The difference are only minor, but sometimes hard to find. Below is a list of the specifics you will encounter. In the process some basic files are offered for *.exe and *.com files, for handling macros, and for handling the
standard library.
First of all valarrow is a .86 assembler meaning that you can not use any code that is .286 , .386 or .486. Especially the use of extended registers like EAX is not supported, and neither are all specific .286, .386 and .486 and pentium instructions.
Second the use of dos segment ordering, and all other red tape directives is not supported by the combination of the assembler and the linker. The meaning of this is that you have to do the ordering of segments yourself. Later on when we are considering macros I will fix this point with a .dosseg macro which comes with other
fix_ups too!@!
Third is that unlike masm, where dos segment ordering is possible, you always have to put assume statements in the head of your files. Otherwise the assembler does not know where to find your code or data. An appropriate example of the statements when you make use of a code segment with the name code_seg and a datasegment with the name data_seg would be :
assume cs: code_seg, ds: data_seg
The fourth specific costed me a few hours and even then someone else came up with the solution. The way you set up a stack segment in valarrow is done like this:
stack_seg segment stack
stackjes db 100h dup(?)
stack_seg ends
So do not use any quotte signs around stack! A basic file exebase.inc file
can be downloaded to get started with making exes in valarrow. Since
valarrow loads segments in the order listed you should be careful
with the listed segment ordering. After the first definition
of the segment, however the loading order is established. It is
possible to declare a code starting point in a executable by ending
your program with end label instead of end.
In any case be sure to insert a newline after the end [label]
statement, since valarrow otherwise does not read the end
statement correctly( and encounters an EOF before 'end')
Fifth also costed some trail and error. To make a *.com program instead of an
executable you have to:
1)Start your code with org 100h
2)Use at least one procedure or startlabel and identifie it as
startpoint of the code with:
end label
Since *.com files are generally not above 64 KB, it has become a habit
not to use data_segments inside *.com files, but instead declare data
at the top of your program and jump over it to the code start( label).
However: both using *.com files bigger 64 KB, and using multiple
segments is possible. Since valarrow does not support runnable
files bigger then 64 KB this possibilitie is just theory for now.
A basic file combase.inc can be downloaded to get started with making
*.com files in valarrow.
A sixth point has to be made in regards to the dgroup statements used
in masm. As far as i know the simplified directives like .dosseg,
.data and .stack are not supported by valarrow.
That is why you can not simply put a code statement in that refers to
dgroup, but you have to first define the group explisit.
Defining a group is however pretty straightforward:
dgroup group data_seg, stack_seg
After that you can refer to dgroup inside your code segment in the
same way that the masm source does it:
mov ax, dgroup
mov ds, ax
The seventh feature of valarrow that is absolutely necessary to work
your way through is the way segments are ordered across files. Each
segment in each file is considered another segment. Even when they
share the same name. When you have reached the stages of finishing
the dskpatch.exe, you might somewhere notice that some procedure
or variable is not reachable because of this local segments.
Luckely there is a simple work around this too. By simply declaring
every same named code and datasegment public you will create only
one code and one datasegment. So for instance when you state in both
fantoom.asm and in dskpatch. asm exactly:
code_segment public 'code'
......................
code_seg ends
data_seg segment public 'data'
.......................
data_seg ends
There will be created only one code segment with the name code_seg
and only one datasegment with the name data_seg. You can control
this by making the linker output a *.mapfile....
The eight feature of valarrow is that its error message are a crime
against humanity. As far as I can see that is the only serious
drawback of the program. There are a few errormessages that the
assembler generates at pass two when there is some problem with
resolving any label. Usually that message is something like:
jmp/call to different CS
The real hack is that those message usually follow at correctly
resolved jmps/calls. The only thing that it says is that there is
somewhere a label reference wrong, but not where. Also you should
be aware if the assembler uses case sensitive labels or not, since
that could make a label reference invalid too.
Structures
Within valarrow you can use structures of variables in the following way:
LOVE STRUC
Howlong DD ?
Howmuch DD 2345H
LOVE ENDS
MyGirl LOVE <>
YourGirl LOVE <0,?>
You should notice that you do not only have to define the structure but that you have to declare the variable
that uses the structure too. You can initialize values for the structure or not. Thats up to you. After you have declared
this MyGirl, YourGirl variables you can proceed with using the variables MyGirl.Howlong, MyGirl.Howmuch,
YourGirl.Howlong,YourGirl.Howmuch. You can even nest structures with structures and with arrays, and also
make arrays of structures. Lastly , unlike for instance QBASIC you can of course declare arrays within your
structures...That are all advanced features that are left for the readers to exercise with...
Macros
You can use macros inside your asm program. Macros are extremely useful when
you have some code you repeatedly use in your programs. For an example I use a well
known macro by Ray Moon:
@WRITE MACRO WHAT, WHERE,LENGTH ; Write String to device or file
mov dx, offset WHAT ; DS:DX => WHAT - DS assumed by macro
mov cx, LENGTH ; CX = String length
mov bx, WHERE ; BX = Filehandle
mov ah, 40h ; Request write to device or file
int 21h ; Call DOS
ENDM
This macro writes the string to whatever file or device you specify. The nice thing about the
interrrupt is that you do not have to write other code for printing to screen or file. The nice
thing of using a macro is that maintainance of your program is greatly facilitated.....
Later in your program you can call that macro INSIDE your code segment (the macro
does not have to be in it..) like this:
Code_seg segment 'code'
Assume cs:Code_seg, ds:Data_seg, es:Code_seg,ss:Stack_seg
mov ax, Data_seg
mov ds, ax
@write what,1,6 ;call the macro
mov ax, 4C00h ;quits without error
int 21h
Code_seg ends
Data_seg segment 'data'
what db 'hallo',0
Data_seg ends
Stack_seg segment stack
stackjes db 100h dup (?)
Stack_seg ends
end
For even better maintainability of your programs you can make a big file( say BIG.MAC) that contains all your
macros. After that the only thing you have to do is to use another feature of assemblers :
Include files
You can use the INCLUDE directive to include a file inside your program. The program pointed to by the directive will
effectivaly replace the INCLUDE statement at the exact place you specified. Assuming you
made big.mac containing the write macro that would shrink our program down to:
include big.mac
Code_seg segment 'code'
assume cs:Code_seg,ds:Data_seg,es:Code_seg,ss:Stack_seg
mov ax, Data_seg
mov ds, ax
@write what,1,6 ;call the macro
....etc ... etc [ same as above]
Note that this code will create the exact same*.obj file as the file that was mentioned when we talked about
macros. It is most useful for maintaince of often used macros. The drawback is that all text inside the macro
file is included in your program. When you have a lot of macros and your program does only use one of them that
seems to be a waste. That is why the concept of run time libraries is developed. Run time libraries provide pre-
assembled procedures which you can link into your program with the INCLUDELIB directive. But, alas, it seems
like VALARROW does not support this...That would point me to a few other useful features of MASM that
valarrow does not support:
Not supported features
Valarrow does not support the following MASM features as far as I know:
INCLUDELIB a feature making it possible to link in precompiled run time libraries
TYPEDEF a feature making it possible to declare your own types( INTEGER etc..)
EXTERNDEF a feature making it possible to declare a variable both public and extern
INVOKE a feature making it possible to call a procedure with arguments
STDCALL, SYSCALL features specific procedures(caller cleanup, callee cleanup etc)
VARARG a feature making it possible to use variable nr of args in procs, macros
LANGTYPE keywords like .pascal or .basic, featuring specific call prolog/epilog code.
USES a feature making it possible to specify which registers a procedure uses.
REPEAT/WHILE/FOR featuring HLL concepts usable(aaachh) in asm.
ALL .386 FEATURES like 32 bit segments, 32 bit code, 32bit instructions
There may be more which I forgot about, and also it might be possible that the directives above are
supported under some different names. This is just the info as far as I know about it.
However, as you might have suspected, macros and include files are of much more use then we have seen
so far. Even some of the limits above can be overcome with some clever macros. And also very important
is that you often needs macros to use some librarie. Libraries are very useful for asm programmers,
as I stated above. Although includelib is not supported by valarrow, freelink supports the
linking in of libraries. Macro uses in valarrow, and also the use of a librarie called the stdlibrarie
is fully discussed in another page: highlights.
This page will continue with the basic description of valarrow/freelink specifications.
The commandline compiler
You can use the assembler from the dos commandline. It uses the following syntax as far as I know:
The files mentioned in the commandline defaults to the following extensions:
Inputfile.asm
Outputfile.obj ( default= Inputfile.obj)
Listfile.lst ( default=NULL.lst(none))
Crosref.crf( default=NULL.crf( none))
The meaning of that is that you can leave the extensions out if you want them to be default.
EX 1: DEFAULT EXTENSIONS
ASM FILE,FILE,FILE,FILE;
This will create the files file.obj, file.lst, file.crf from file.asm.
Another meaning of that is that you can override the extension of the list file.
The commandline accepts between 1 and 4 fields( inputfile MUST be there) ended with a semicolon
All fields after the semicolon are accepted as default without prompting.
EX 2: MINIMAL COMMANDLINE
ASM FILE;
This will create the file file.obj from file.asm, since both the list file and the crosref file are not created by
default.
A field can be replaced by a placeholder colon, in which case file.ext will be created.
EX 3: COMMANDLINE WITH PLACEHOLDERS
ASM FILE, , ;
This will create the files file.obj and file.lst from file.asm.
When you did not ended the commandline prematuraly with a semicolon and did not specified placeholder
colons for a field then you will be prompted by the assembler for the filename.
EX 4: COMMANDLINE WITH PROMPTING
ASM FILE, , ,
Since there are placeholders for the obj and the list field this commandline will create the files file.obj and file.lst from file.asm and after that prompts you for the name of a crf file.
Sometimes you might not wanna overwrite an existing list file after making some changes in the source, but still want
another listing. In that case you can use an override for the list file extensions. This will also work for obj or crosref
files.
EX 5: COMMANDLINE WITH EXTENSION OVERRIDE FOR LISTFILE
ASM FILE, , ,.NEW,
Since there is a placeholder for the obj field, and the list extension is overriden, and the crossref field is open this commandline will create the file file.obj and file.new from file.asm and after that prompts you for the name of a crf file.
I will give you the *bat file I use to invoke valarrow's assembler with nothing but a default listing.
The commandline linker
The freelink program is very well documented so there is no need for me to brag about it!
Example: FREELINK /C BASIS1.OBJ
I repeat that when you have read and understanded this comments then i am absolutely sure
you can work your way through P. Nortons book. When you want some source, in valarrow, of the programs developed in the book you can mail my for it, since i got them all working. Also i hope that when you know of some other undocumented feature of valarrow you will mail me so that i can update this page....This last question is important since the power of the tool is sometimes equivalent to easiness with which you can use it. After all: an assembler is a tool and should not develop to a goal "an sich"! As sort of a last
post here's the bat file I use to run valarrow(valbat.zip)