USING BASIC - 1
So you like using BASIC. I can't blame you. BASIC has several
very nice features.
(1) Its graphics interface is easy to use and is very
powerful. If you want to draw lines, circles, patterns or
other graphics images, you can do it. Your only limitations
are the aspect ratio of the screen and the possible screen
colors. These limitations have to do with hardware, not with
(2) Its string handling capabilities are unparalleled. If
you want to have an array of strings like the following:
DIM STRING.ARRAY$ (50, 25) ' 1250 elements
and some of the elements are only a couple of characters
long but some of the strings are several hundred characters
long, BASIC is the ONLY language that can handle it
correctly. In fact, if you wanted one of the strings to be
1000 characters (it's allowed in the most recent BASIC),
then you would need 1.25 megabytes for this array in C or in
PASCAL. This would probably be too big for the computer.
BASIC, on the other hand, implements this without wasting
any space in memory.
BASIC has a few things that require a little more work than with
other languages. It has strings, integers, and floating point
numbers but it is missing characters and unsigned numbers - these
can be implemented by using integers (if you are careful). This
is not all that limiting.
If BASIC is so nice, why do I think that you should have some
experience with a structured language before doing assembler? It
all has to do with data INTEGRITY. The question is, are you sure
that you haven't inadvertantly screwed up your data? There are
two ways that this might happen. You need to know how BASIC works
to understand the problem.
A variable name in BASIC consists of a name followed by a type
identifier. The identifiers are '%', '!', '$', '#' (double
precision) and possibly '&' (long integer). The name:
is NOT a variable inside of BASIC while:
The PC Assembler Tutor - Copyright (C) 1990 Chuck Nelson
The PC Assembler Tutor mmii
are all valid variables. In fact, all three can be in the same
program, as we shall see shortly. I just said that that first
example is not a valid variable inside of BASIC, but that is
exactly what you have been writing since the first time that you
wrote a BASIC program. What's going on here? Well, when the BASIC
interpreter or compiler reads the text file, it reads the name
and the identifier. If the type identifier is missing, it tacks
the default identifier on to the end of the name.
What's the default type identifier? The answer is '!'. BASIC
maintains a default list. The legal first characters in a name
are A-Z. For each legal first letter, there is an entry in the
list which says what the default type for that letter is. When
you start the program, the type list looks like this:
When the interpreter sees a name without an identifier, it takes
the first character of the name and goes to the default-type
list, gets the appropraiate type identifier for that first
character, and adds the identifier on to the end of the name.
Externally (in your text file) there may be names without type
identifiers, but internally (inside the interpreter/compiler) ALL
variables have the type identifier after the name.
Though the list starts out with all '!'s, you can change this
list with a DEF statement. Here are some DEF statements and how
they change the list. I am assuming that we are always starting
at the beginning of the program (with all '!'s).
DEFINT A-Z ' This is probably your favorite
This last one is a recipe for disaster, but it's legal.
Have you understood everything so far? Then let's go on. This
ability to NOT use the type identifier leads to laziness. The
usual thing is to always identify strings with a '$' but to be
rather lax about the distinction between integers and floating
Now we get to the problem. Look at the following code:
BASIC I - Using Basic mmiii
10 DEFINT A-Z
20 FOR I = 1 to 5
30 LARGE.NUMBER! = 300.0 * I
40 SMALL.NUMBER! = LARGE.NUMBER / 7
50 PRINT LARGE.NUMBER!, SMALL.NUMBER!
60 NEXT I
If you can't see the error, I forgot to put the '!' after
LARGE.NUMBER in line 40. The problem here is that BASIC is not
going to complain. When it sees LARGE.NUMBER without a type
identifier, it will go to the default list (because of the DEFINT
statement, all defaults are integer) and put a % after it. BASIC
has created a SECOND variable with the same initial name, but a
different type. This is not because you wanted it to, but rather
because you forgot a '!'. Lets do a BASIC program. Here's some
******************* NINJA.BAS *******************
10 ' place for defint statement
30 ' enter all the data
40 NINJA% = 20
50 NINJA! = 4.7134E+13
60 NINJA$ = "Hey dude!"
80 NINJA$ (0) = "howdy! "
90 FOR I% = 1 TO 5
100 NINJA$ (I%) = NINJA$ ( I% - 1 ) + "doody! "
110 NINJA! (I%) = I% * 25.31
120 NINJA% (I%) = I% * 3
130 NEXT I%
150 ' print all the data
160 PRINT NINJA%, NINJA!, NINJA$
170 FOR I% = 1 TO 5
180 PRINT NINJA% (I%), NINJA! (I%), NINJA$ (I%)
190 NEXT I%
200 PRINT NINJA , NINJA (3)
I actually want you to run this through your BASIC. I have
defined SIX different NINJAs. They are:
2) NINJA% ( )
4) NINJA! ( )
6) NINJA$ ( )
where the parentheses indicate an array. If I had gotten carried
away, I could have included 4 more NINJAs for double precision,
The PC Assembler Tutor mmiv
double precision array, long integer and long integer array.
Running this through my computer I get:
20 4.7134E+13 Hey dude!
3 25.31 howdy! doody!
6 50.62 howdy! doody! doody!
9 75.93 howdy! doody! doody! doody!
12 101.24 howdy! doody! doody! doody! doody!
15 126.55 howdy! doody! doody! doody! doody! doody!
Notice that I have 3 different array types and 3 different
variable types. As you can see from the bottom line (which prints
the defaults), the default here is '!'. If we now put DEFINT A-Z
on line 10:
10 DEFINT A-Z
everything will stay the same except the bottom line which now
which are the integers. Finally, if we have DEFSTR A-Z
10 DEFSTR A-Z
Hey dude! howdy! doody! doody! doody!
as the bottom line of output. If you didn't know all of this
before, make sure you have assimilated this before going on.
PASCAL and C
Both PASCAL and C require you to account for every variable. You
need to specifically state what kind of variable it is and you
need to enter it in a list of variables used in that block of
int ch, variable1, variable2, variable3 ;
char long_array ;
A name can be used in only one way in any block of code. If you
try to use it differently, the compiler will generate an error.
Though people moan and groan about having to specifically list
all the variables used in a block of code, over time they get
used to it. It offers two advantages.
(1) No variable can be inadvertently used in an incorrect
way (used as a string when you wanted an integer, used as an
integer when you wanted a floating point number, etc.).
(2) There can be no variables which are misspelled, are left
BASIC I - Using Basic mmv
over from a previous version of the code or appear by
mistake, without both the compiler and you knowing about
Slightly modifying names is one of my major problems. I might use
'long_array' and 'longarray' in different places in the C code,
though I want the same thing. C will catch this, BASIC won't.
Every time BASIC encounters a slightly different name it simply
creates a new variable (and normally sets it to 0). In programs
larger than a few pages, this situation is almost impossible to
detect or control.
THE RANGE OF A VARIABLE
When talking about PASCAL and C I kept using the word BLOCK. Both
languages have a modular (or block) design. The philosophy behind
this is that when you write a program you want to divide a task
into a number of distinct subtasks, and you don't want these
subtasks to interfere with each other. You put each of these in a
subprogram. In BASIC you can put sections of a program in
subprograms too. This is good programming practice. There is a
difference, however. In C and PASCAL, a variable is valid ONLY in
the block in which it is declared (unless you take specific steps
to make it universally valid). If you try to use this variable in
a different block of code the compiler will generate an error -
it literally has no information about where this variable is. In
BASIC, all names are valid everywhere in a file. If on page 1 you
210 CURRENT.PRICE! = 427.11
you may want to use this as a constant number throughout the
program. But if in a subprogram on page 23 you have:
12060 CURRENT.PRICE! = 0
you have changed the value. You're saying to yourself "But why
would I change a variable like "CURRENT.PRICE!"? You probably
wouldn't. But you will have dozens and dozens of variables around
with names like I, J, K, COUNT, START, STARTING.NUMBER,
STARTING.VALUE, TOTAL, RESULT and LAST.VALUE (whatever their
type). It is exactly these that will be corrupted in BASIC but
will be reliable in C or PASCAL.
1920 MINIMUM! = RATE! * 5.0
1930 MAXIMUM! = RATE! * 7.32
1940 COUNT% = (MAXIMUM! - MINIMUM!) / 3.0
1950 CALL CHECK.ANSWER
1960 PRINT COUNT%
In this section of code, did 'CALL CHECK.ANSWER' change any of
the four variables MINIMUM!, MAXIMUM!, RATE! or COUNT%? In BASIC,
we hope so, but we can't be sure. In PASCAL or C we KNOW that it
The PC Assembler Tutor mmvi
didn't change any code. This is the difference between a
structural engineer HOPING that a bridge won't fall down and
KNOWING that a bridge won't fall down.
In fact, the PASCAL and C programmers will probably be annoyed
when they start using assembler because in assembler, ALL names
are valid everywhere. More importantly, however, these
programmers will make great efforts to insure that all constants
stay constants and that each variable is used for one job only.
Finally, some BASIC programmers still do most of their
programming using GOTO statements instead of CALLs. This is the
antethesis of modular programming and is called spaghetti
programming. The code winds up as an intertwined mess. If you are
one of these people, once you start writing assembler code it
will be impossible to figure out what the code is doing once it
is longer than a page or two.
All that being said, if you feel that your programming style is
clear and orderly, have a fun time learning assembler. When you
are done with all the chapters, read the second BASIC appendix on
the problems associated with linking a non-BASIC subprogram to a