NewBasic Assembler
(32 bit version)
Version 00.25.79
Freeware
Forever Young Software
(C)opyright 1984-2003
All rights reserved
25 May 2003
**** Version 00.25.00 and up require a 386+ ****
**** and a DPMI server (Windows DOS box) ****
**** (see requirements below for other DPMIs) ****
** Please always read WHATSNEW.TXT on each update for possible changes **
Please read 'Precautions' near the end of this documentation. It has to do
with some features that are not yet in NBASM that you will need to know about
using libraries and the .external directive, as well as the 32 bit
instructions.
Please read "Difference between NBASM and NBASM32 source files" on page 7
Please read page 54 about the new .OBJ file type if you plan on using this
type of DOS output.
Table of Contents
Introduction and Overview
Legal Terms and Conditions ..........................2
What is NBASM indented for ..........................2
What can NBASM do ...................................2
What won't NBASM do .................................2
Difference Between Other Assemblers .................4
Conflicts with Other Software .......................5
System Requirements .................................5
Software Requirements ...............................5
Latest Version ......................................6
Bug report ..........................................6
Mailing List ........................................6
About the Author ....................................6
Difference between NBASM and NBASM32 source files ...7
Using NBASM
Running NBASM .......................................8
Assemble-time Macros ...............................10
Optimizer and Precautions ..........................11
Using the Library ..................................12
Your Source File(s)
Syntax .............................................14
Operands ...........................................16
Memory References ..................................21
Indirect Branching .................................21
Pseudo-Operations ..................................24
Directives .........................................29
Instructions .......................................36
FPU Instructions ...................................42
Structures and Struct ..............................51
Unions .............................................53
Sizeof .............................................54
Pointers ...........................................55
ENUMeration ........................................57
.OBJ files (the small model) .......................58
Miscellaneous Items
Errors .............................................43
Precautions ........................................47
Examples ...........................................48
Appendix A (undocumented instructions) .............49
Appendix B (misc notes on some instructions) .......50
Index ................................................60
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 02
Introduction and Overview
Legal Terms and Conditions
This package is provided to you under the following conditions:
1. This package is distributed as freeware. You may copy the NBASM.ZIP files,
and give them to anyone who accepts these terms, as long as the copies you
distribute are complete and unmodified.
2. There is no registration fee for using this package. However, a note or
comment saying that you have downloaded this package and are using,
deleting, liking, loving, hating, etc., would be appreciated. You can
send all comments to:
fys@cybertrails.com
Commercial, government, and educational institutions and training
facilities must be registered in order to use NBASM. Please contact me
for special terms and conditions.
3. This package may not be sold to anyone. If this package is distributed on
a disk, any fees collected must be for media and handling and may not
exceed ten US dollars.
4. I am not to be held liable for any damages, of any kind, arising from any
failure of any programs in this package or any programs created with this
package. Use at your own risk.
5. You can sell or distribute any program that you have written or modified
using this assembler. There is no fee for any executable file produced
with this package as long as this executable file is for non-commercial
use. If you use this package for commercial use, please contact me for
special terms and conditions.
6. Sorry for all the legalities. This is to protect me as well as protect
you.
What is NBASM indented for?
1. NBASM is indented for users that want to learn assembly language as well
as experienced users who want to create assembly language projects.
2. NBASM can be used to create small or large projects. There are no
size restrictions.
3. I created NBASM mostly for the enjoyment and to learn how to create an
assembler. You may use NBASM to its full capabilities, but please take
note that it does contain bugs and/or errors. If you find a bug and/or
error, please let me know. I am constantly adding new things to NBASM and
fixing bugs and errors is part of the fun.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 03
What can NBASM do?
1. NBASM takes a text file, consisting of mnemonics, user-defined symbols,
numbers, and pseudo-ops, and produces a file of corresponding machine
language for the 8086/88 through the Pentium processors.
With the use of a few "red tape" items, you can produce REAL mode code,
or 32-bit PMODE code using NBASM.
2. Your source files, main file and all include files, are not restricted and
can be of any size.
3. NBASM supports long filenames, and uses long filenames by default if the
current operating system has LFN support.
4. NBASM is capable of processing a few output file types:
1. COM files that are ready to execute by a MS-DOS compatible Operating
System.
2. SYS files, that if correctly written, can be used for boot sectors,
device drivers, etc. Also called "flat binary" files.
3. OBJ files that are compatible with MS compatible 16-bit or 32-bit .OBJ
files. ** Please see page 54 for a few notes about the .OBJ format. **
5. External variables and procedures will be supported once the .OBJ part has
been fixed. (see page 54 for more)
6. NBASM is 'fairly' fast. The source to NBASM is in C and compiled with the
32-bit DJGPP. You can get DJGPP from http://www.delorie.com/djgpp. A
project that I am currently working on is a minimum of 16 files with a total
of about 400,000 bytes in text, producing a 20k binary takes about 30
seconds to complete on a P-233 machine and about 10 seconds on a PIII-800
machine.
7. NBASM is easy to use. Even though NBASM requires a few "red tape"
directives, once you have these at the top of you source, there are not
many more "red tape" items needed. Though once you get to know these "red
tape" items, they make your source a lot easier to read and handle.
8. NBASM has a full function listing capability, listing output to a .lst
file for your debugging purposes.
9. NBASM has many error messages to help you catch the errors in your source.
What won't NBASM do?
1. Macros are not supported. Currently, I do not have plans to support user
defined macros. However, if the interest of the user warrants them, I may
add this feature.
2. NBASM doesn't support any Windoze/Linux/UNIX/etc. file formats. DOS is
assumed on all projects as input and output.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 04
Difference Between Other Assemblers
Here I will try to explain the differences between NBASM and some other
assemblers and how to modify your source code to work with NBASM.
While maybe some of the following assemblers support them, NBASM does not
support the following:
1. User defined Macros
2. All of the x87 instructions (I hope to have the rest included soon)
MASM 5.1x (Microsoft)
There are little differences between NBASM and MASM 5.1x. I have tried to
make NBASM as close to MASM as I could and still satisfy my wants. If you
use the newer/easier segment directives of MASM, you will have to change
your source very little to assemble with NBASM.
NBASM does not support the .DATA?, .FARDATA, & .FARDATA? segment
directives.
MASM NBASM
end label .end label
repx movsx repx
movsx
count dup(value) dup count,val
mov byte ptr [xxxx],xx mov byte [xxxx],xx
mov word ptr [xxxx],xx mov word [xxxx],xx
mov dword ptr [xxxx],xx mov dword [xxxx],xx
(along with a few other minor items)
TASM (Borland (Inprise))
I have not used this assembler. However, I have heard that this assembler
has a directive to make it 'act' like MASM.
NASM (NetWide Assembler)
NASM has very few "red-tape" items if none at all, for which you will
have to add a few for NBASM. After this, the following list are the
differences I have found:
NASM NBASM
mov dx,label mov dx,offset label
(I know there are more. I will hope to list them here soon)
CHASM 4.1x (David Whitman)
NBASM is similar to CHASM 4.1x. However, NBASM uses segment directives,
the .model directive, and some other advanced features. There are a few
modifications to CHASM besides the segment directives to make your source
assemble with NBASM.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 05
CHASM NBASM
mov bx,offset(symbol) mov bx,offset symbol
symbol ds 10,0 symbol dup 10,0
SHx reg/ROx reg SHx reg,1/ROx reg,1
label label:
(along with a few other minor items)
NBASM also wants the .end directive at the end of your source.
Conflicts with Other Software
1. MCAFEE in a Win9x DOS session
MCAFEE's VSCAN for Windoze 9x makes NBASM pause just after the Copyright
information that is printed to the screen. It is probably scanning the
.COM file for viruses before it writes it to disk. To stop the 'pause',
right click the 'V' (VirusScan) icon in the task bar and click on EXIT.
Once you finish your DOS session, you can reload VirusScan.
If you don't get the 'pause', then there is no need to unload VirusScan.
NBASM does not contain any intentional viruses. However, it is always
safe to scan all files you get from the internet or any type of disk.
No other known conflicts. Please let me know if you find one.
System Requirements
1. Intel compatible 386+ machine with a "proper" DPMI server.
The following items are valid DPMI servers:
MS Windows Dos box, QDPMI, 386Max, NWDOS, OpenDOS, OS/2,
Linux DOSEmu, and DJGPP's CWSDPMI.
You can get 'CWSDPMI - DPMI server' from:
ftp://ftp.bu.edu/pub/mirrors/simtelnet/gnu/djgpp/v2misc/csdpmi5b.zip
or
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2misc/csdpmi5b.zip
(see error codes for more information)
2. a disk drive with a minimum of 256k of free disk space
(is that all?) plus room for the .COM and .LST file(s).
3. a minimum of 1 meg free extended memory.
4. a keyboard ( Duuhh! =:o) )
5. a printer capable of text printing (for hard-copies right?)
Software Requirements
1. A DOS Protected Mode Interface (DPMI) server:
Windows DOS box, QDPMI, 386Max, NWDOS, OpenDOS, OS/2, Linux DOSEmu,
or DJGPP's CWSDPMI.
2. Some sort of viewer to view this document. (But you are reading this
right now, so you got at least that much, right?)
3. A similar editor to create DOS ascii text files. (EDIT.COM|EXE)
4. PKUNZIP/WINZIP to unzip the zip file. Again, you are reading this file,
so you must have one of these :0)
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 06
Latest Version
You can get the latest version of NBASM and utilities at:
http://www.cybertrails.com/~fys/newbasic.htm
Bug Report
NBASM is not perfect and there are bound to be bugs in it.
Please report bugs to:
fys@cybertrails.com
http://www.cybertrails.com/~fys/newbasic.htm
Known Bugs/Errors
Please see the included README.TXT file for a list of known issues.
Mailing List
I have an announcement mailing-list which I use to announce news and updates
about NBASM and other items pertaining to NBASM. It is a moderated list and
will only be used for NBASM announcements.
If you would like to receive mail each time I make an update or announce
something about NBASM, please send an empty email message to:
nbasm-subscribe@yahoogroups.com
To unsubscribe from the list, please send an empty email message to:
nbasm-unsubscribe@yahoogroups.com
You can also view the archived messages at:
http://groups.yahoo.com/group/nbasm
If you have any problems with the above mailing list, please let me know at:
fys@cybertrails.com (Please include your Yahoogroups login in name)
I don't plan on more than about a single message per week at the most. So
don't worry about me filling your "inbox" :-)
About the Author
I am a full time Freelance DOS and Windows 9x/NT programmer. I have been
programming since 1984 and most of these projects for the Intel x86 systems.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 07
I have been making a nice living from my work, and with your much
appreciated support, I will continue to improve my products, and enhance
them with new features and capabilities.
I can be reached at the following addresses:
http://www.cybertrails.com/~fys/index.htm
fys@cybertrails.com
Forever Young Software
%Benjamin David Lunt
PO Box 875
Taylor, AZ 85939-0875
Difference between NBASM and NBASM32 source files.
The following few minor changes must be made to your assembly source files
for NBASM32 to assemble them correctly.
- The shift operators: NBASM uses < and >, while NBASM32 uses << and >>
(NBASM32 uses < and > for Logical LessThan and GreaterThan)
- The 'org xxh' statement bust be inside a .code/.data block.
(org xxh must be after .code or .data, not before)
Currently, there are no other changes that I am aware of.
With the few changes above, all your existing source code should assemble
with NBASM or NBASM32. The only difference is that NBASM32 has more
features, including handling unlimited files, and a larger symbol table.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 08
Using NBASM
Running NBASM
From the DOS prompt, type: (Items in brackets are optional.)
NBASM source[.asm target.(COM|OBJ|SYS|BIN) parameter list]
source is the filename of your source file. If you do not include an
extension, .asm is assumed.
target, if given, is the name that NBASM will name your target file.
If not given, NBASM will use "source" as the target filename with
The .COM or .OBJ extensions.
parameter list can be any one of the following in any order.
Please note that any parameters are first come, first serve and will
overwrite any parameters previously listed on the command line.
(the '-' char can be substituted for the '/' char)
** All parameters are case sensitive **
/1 - do pass 1 only
does not create a target file. For syntax checking.
/a - align segments in alphabetical order
/A - abort if key press during assembly time
/b - beep if errors were encountered during assembling
/d - do not print diagnostic errors
/h - help screen
/i{} - include path (if {} only, then start from root dir)
specify an include path between the {}'s
/j - same as the .jumps directive
/o - optimize for size
/s - check syntax only
does not create a target file. For syntax checking.
/x - Tells NBASM to create a list file
(the list file as the .LST extension)
/v - view version info
While NBASM is assembling your source, you may press a key to stop
assembly. However, if NBASM was in the process of creating an output
file, it will be undefined. (only if /A used on command line)
NBASM makes three passes over your source file, outputting the listing and
object code on the third pass.
NBASM returns an error code in ERRORLEVEL for use in .bat files. The
following codes are returned:
00h - No error encountered
02h - Error opening file
03h - Invalid path used with /I{} parameter
06h - Target File can not be Source File
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 09
08h - Not enough memory
0Bh - Invalid command line
0Eh - Need DOS 2.0+ or an 80186 or higher CPU
0Fh - Trying to include an already nested include file
13h-FEh - error code of last error found in source code
FFh - Undefined error
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 10
Assemble-time Macros
These macros are assembler time macros. All macros start with the percent
sign (%). Each macro can have one or more parameters. Some macros may
require an ending macro declared as the same macro name but with two percent
signes (%%)
-- %DATA
This macro puts the segment of DS into the operation as a word value for
use in .EXE files. Used only in the small model.
Example:
mov ax,%DATA
mov ds,ax
-- %DAY
This macro replaces itself with an immedate equal to the current day of
the month (1-28, 29, 30, 31).
-- %ERROR "pass_number" 'text to print'
This macro outputs text to the stdout device (screen) when the assembler
gets to this location in the source. Prints what is on this line only,
and requires no ending macro name. The "pass_number" can be 1 - 255,
with 1 being the first pass, and 255 being the last pass.
If anything else, it doesn't print.
'text to print' must be any assembler compatible string.
This macro also increments the ERROR count.
Example:
%ERROR 1 "abc" ; <- must be double quotes for 'small' strings
%ERROR 1 'Print this line on the first pass only'
%ERROR 255 'Print this line on the last pass only'
-- %LINE
This macro returns an immed16 (word) denoting the current line number
that this macro is on.
Example:
mov ax,%line ; this line is on line: %line
-- %MONTH
This macro replaces itself with an immedate equal to the current month
of the year (1-12).
-- %OUT "pass_number" 'text to print'
This macro outputs text to the stdout device (screen) when the assembler
gets to this location in the source. Prints what is on this line only,
and requires no ending macro name.
The "pass_number" can be 1 - 255, with 1 being the first pass and 255
being the last pass. If anything else, it doesn't print.
'text to print' must be any assembler compatible string.
%OUT 1 "abc" ; <- must be double quotes for 'small' strings
%OUT 1 'Print this line on the first pass only'
%OUT 255 'Print this line on the last pass only'
-- %PRINT symbol
This macro prints 32-bit hex(dec) values of the symbol given. The symbol
can be just about any symbol, math function, immediate, etc.
-- %TITLE 'title text'
This macro outputs the title to the .OBJ file if model is small.
If the model is tiny, this macro is ignored.
-- %VER
This macro returns an immed16 (word) denoting the current version of
the assembler. High byte is major version and low byte is minor
version.
Example:
mov ax,%ver ; get the current version of the assembler
-- %YEAR
This macro replaces itself with an immedate equal to the current year.
(2002, 2003, 2004, etc.)
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 11
Optimizer and Precautions
NBASM includes an optimizer with different levels of optimizations.
Currently, there is only one level implemented.
Level 0: optimize for size
If you include the /o switch on the command line and/or use the
.OPTON/.OPTOFF directive, then NBASM will optimize in the following
areas:
1. Optimization #1:
if MOV REG16/32,00
then XOR REG16/32,REG16/32
examples:
if MOV (E)DX,00h
then XOR (E)DX,(E)DX
notes/precautions:
If you are relying on the flags register from a previous instruction and
the optimizer changes the above item, the flags register will be destroyed
by the XOR instruction. If you want to use MOV dest,00h so that the flags
won't be affected by the instruction then do like the following example:
AND AX,45h ; want to use flags later
.OPTOFF
MOV DX,00h ; MOV doesn't change the flags
.OPTON
JZ .... ; use flags from AND above
2. Optimization #2:
if CMP REG,00
then OR REG,REG
example:
if CMP (E)DX,00h
then OR (E)DX,(E)DX
notes/precautions:
Even though NBASM will change an 8 bit register above, there is no size
difference gained. It is done for consistency.
3/4. Optimization #3/#4:
if ADD REG/MEM,1 or SUB REG/MEM,1
then INC REG/MEM DEC REG/MEM
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 12
example:
if ADD (E)AX,01 or SUB (E)AX,01
then INC (E)AX DEC (E)AX
notes/precautions:
Please note that SUB and DEC do not effect the flags in the exact same way.
5. Optimization #5:
if INT 20h
then RET
notes/precautions:
only works in .tiny model (.COM files) with out the use of the .start
directive. Also, make sure that you know that [SP] = 00h. Use .OPTOFF if
you are not sure.
Using the Library
NBASM includes a library for Tiny Model.
For the Tiny model, the library NBASMC.LIB is included. It is a library
of binary code that NBASM appends parts of it to the end of the .com file
when the .external directive is used.
For example, the following source would be assembled and then NBASM would
include the binary code for 'prtstring' at the end of the .com file from
the NBASMC.LIB library file:
.model tiny ; create COM file
.186 ; allow 186 instructions
.external prtstring ; include the code for prtstring
.code ; start of code segment
push offset msg1 ; use library function (prtstring)
call prtstring ;
int 20h ; exit to DOS
msg1 db 'This string gets printed to the screen',0
.end
Note: If a symbol is declared external via .external but is not used in
the code, NBASM will NOT add the associated code to the end of the .com
file. For this it is safe to declare all external procedures you might
use and not have to worry about them taking up unnecessary space in the
.COM file. However, they will take up space in the symbol table at
assemble time.
Note: When LIBMAN creates a library, it adds a CRC to each function added.
NBASM checks this CRC to make sure that the library function wanted is not
corrupted before it adds the necessary binary code.
See http://www.cybertrails.com/~fys/newbasic.htm for more about LIBMAN.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 13
Please note that all code that is used/called from a library with this
technique is added to the end of your .com file. So if you plan to use
the remaining memory after your .com file, please take in mind the size of
the code included by the library, or you might overwrite the code and
crash the machine.
I plan to add some code and documentation to NBASM to allow the user to
find where the end of this added code will be. Until then, be careful
about assuming where the code is and how long it is.
Please see Example #2 at the end of this documentation for example
on the .external directive. Also see DEMO1.ASM for another example.
Please read the documentation for the library on how to use each procedure
included in the library(s). This documentation is in NBASMC.DOC included
with this package.
NBASM will soon include a library for the 'small' model (.OBJ type).
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 14
Your Source File
Syntax
NBASM accepts a standard DOS text file for input. Lines may be any
combination of upper and lower case characters. NBASM does not distinguish
between the two cases. Every thing except quoted strings are automatically
converted to upper case during the parsing process. Thus, SYMBOL, Symbol,
and symBol all refer to the same symbol.
The following characters or reserved by NBASM:
space (ascii 32)
comma (ascii 44)
single quote (ascii 39)
double quote (ascii 34)
semi-colon (ascii 59)
underscore (ascii 95)
dollar sign (ascii 36)
percent sign (ascii 37)
backslash (ascii 92)
NBASM will change a null char and a tab to ascii 32 (space) if found in
your source code. This happens in all lines, INCLUDING quoted
strings. So if you want to use these types of chars in a quoted string,
you must use the ascii value as a literal.
Example:
string db 00,'some chars',09,13,10 ; etc...
Each source line must be less than 4096 characters long and have the
following format (see the backslash note below for lines longer than 4096):
Label: Operation Operand(s) ; comment
The delimiter, which is a space or a comma, separates the different fields
of an input line. Any number of either delimiter may be used to separate
fields.
If you place a backslash at the end of your line, then NBASM will get the
next line as part of this line. Anything passed the backslash on this line
will be ignored. Both of the following are the same:
mov ax, \ ax = 200h mov ax,200h ; ax = 200h
200h
There is a limit of 128 tokens per line including all lines used with the
backslash.
Please note that when using this operator and an error occurs, NBASM will
point to the last line of the set of lines that use this operator.
Explanation of Fields
Label: A label is a string of characters, beginning in column 1. Depending
on the operation field, the label might represent a program location for
branching, or a memory location. Labels can be as many characters long as
wanted, though on average, NBASM allows about 131072 bytes for symbol names.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 15
******** NOTE: Anything beginning in column 1, except a comment or
directive, is considered a label.
There are two variaties to denote this type of label. The label
name only or the label name with a full colon (:) after it.
labelname
or
labelname:
If you use the first type, (with out the full colon), it MUST start
in COLUMN ONE of the line. If you use the second type, (with the
full colon), you can have it start in any column as long as there
is no token before it.
Other than that difference, the two are identical.
NBASM allows the use of the 'Unique' Label directive called, '@LABEL'.
When NBASM comes to this directive, it will do one of two things depending
if this will be a label or symbol. If it is to be a label, then NBASM
will put a 'Unique' name as the label. NBASM starts with 'NB0000' as the
label and then increments to 'NB0001' for the next and so on.
If you put a label that has this name and also use @LABEL, you might
receive errors.
If @LABEL represents a symbol other than a label, NBASM will put the
current 'unique' name in as this symbol name. So with this technique,
every '@LABEL' reference that is not in column 1 will point to the next
label that is in column 1 AND named '@LABEL'. This allows you to use more
than one to point to the same label reference. Please note that this will
only work in the forward direction. See Example #1 at end of this
document for more information.
Operation: Either a pseudo-op or an instruction mnemonic.
Operand(s): A list of one or more operands, as defined on page 16,
separated by delimiters.
Comment: Any string of characters, beginning with a semicolon. Anything to
the right of a semicolon will be ignored.
If you want to have a lot of text and don't want to start each line with a
semicolon, then use the COMMENT <char> ... <char> command. The first char
of the next token following COMMENT will denote the start of the comment.
NBASM will start with the NEXT line and search for that char again. Once
found, assembly starts on the NEXT line after the found char.
Please Note: COMMENT <char> ... <char> will not work on the same line.
Use the semicolon (;) for this.
Example:
COMMENT # all the text and code that is on this line
and this line
and this line
# and any thing on this line will NOT be assembled.
; ASSEMBLY resumes here
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 16
Operands
The following operand types are allowed
Immediate data: A number, stored as part of the program's object code.
Immediate data is classified as either byte; expressible as an 8 bit
binary integer; word, expressible as a 16 bit binary integer, or dword,
expressible as a 32 bit binary integer. If context requires it, NBASM
will left-pad byte values with zeros to convert them to word values and
the same with word to dword values.
Attempts to use a word value where only a byte value will fit will cause
an error message to be printed, and the same with dword values.
Immediate data may be represented in 7 ways:
1. A signed decimal number in the range of
-2147483648 to 2147483647 ( signed)
0 to 4294967296 (unsigned)
Example:
MOV AL,22
MOV BL,-15
MOV BX,-1000
MOV EBX,-1000
MOV DX,65535
MOV EDX,-1
MOV EDX,12345678
2. A series of up to 8 hex digits, followed by the letter H (lower or
upper case). All hex numbers should start with a numbered digit of 0-
9 and should be in the range of: 0h to FFFFFFFFh
Example:
MOV CL,0FFFFFFFFH ; -1
MOV CL,-1H ; -1
ADD DL,0FDh
MOV CX,1234H
MOV CX,-1234H
MOV ECX,12345678H
3. A series of up to 32 binary digits (0|1), followed by the letter B
(lower or upper case). Since 32 bits is hard to keep track of, you
may use a spacer (_) to help you keep track of each part of a bit
map.
Example:
AND CL,00010010b
MOV CX,1100000011111111b
MOV CX,11101010_11010111b ; <- spacer used
MOV CX,11_0000_111_0000_111b ; <- spacer used
MOV ECX,11101010_11010111_01100101_01010111b ; <- spacer used
MOV ECX,11000000111111110100000011111111b
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 17
4. A symbol representing the types above defined using the EQU pseudo-op.
Example:
TEMP EQU $ ; temp = this location
MASK EQU 10h
MASK1 equ 1000h
MYSTR equ "I was here"
or CL,MASK
xor ax,mask1
EQUates simply are used to replace the symbols text in the code
below it. For instance, the above MASK1 equate declares an
NBASM internal string variable to "1000h". Everywhere the word
MASK1 (any string case) is found in the code below it is changed
to "1000h" (with out the quotes).
Example:
; If I have already declared MASK1 above, then
; The following code in my .ASM file
mov ax,MASK1
; will be changed to
mov ax,1000h
;with NBASM's preparser.
; *it will not be changed in the .ASM file*
This is similar to C's #define's.
You may use Strings, and Literals as well as numbers. All EQUates
are considered strings until used.
Example: (using the above MYSTR equate)
alabel db MYSTR
; will be preparsed to
alabel db "I was here"
**** Please note that all EQUates should be before you actually use
the symbol in your code. You will get a phase error if you
define the EQUate after you use the symbol in your code.
5. The offset of a label or storage location returned by the OFFSET
operator. OFFSET always returns a word value in real mode, and a dword
value in protected mode code. OFFSET is used to get the address of a
named memory location, rather than its contents.
Example:
mov di,offset Buffer ; 16-bit rmode
mov edi,offset Buffer ; 32-bit pmode
6. The ASCII value of a printable character, represented by the character
enclosed in single quotes. Thus, the following lines will generate
the same object code:
MOV AL,65 ; ascii code for 'A'
MOV AL,'A'
MOV AL,"A" ; *error*
; these two lines are the same
MOV AX,4142h
MOV AX,'AB'
; these two lines are the same
MOV EAX,41424344h
MOV EAX,'ABCD'
7. In the form of a math equation enclosed in ( )'s. You can use any
form of a constant number, an EQuate, or a predefined symbol and
use the following operators:
Note that all numbers are considered 32-bit. This means that even
though 0FFFFh would represent -1 if words were used, 0FFFFh = 65535
in any math function. If you want -1, use one of the following:
-1, 0FFFFFFFFh, 11111111111111111111111111111111b, or ~0
The following items allow 32bit numbers as both the operand and the
result:
+ add (32bit add 32bit)
- subtract (32bit sub 32bit)
| or (32bit or 32bit)
^ xor (32bit xor 32bit)
& and (32bit and 32bit)
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 18
The following items allow 32bit numbers as only the number to be
worked on. The "work with" number must by 16 bit and be a positive
integer:
* multiply (32bit mul 16bit)
/ divide (32bit div 16bit)
>> shr (32bit shr 16bit)
<< shl (32bit shl 16bit)
The following item allows only one operand as a 32bit number:
~ not (not 32bit)
Negative integers are allowed in the first 5 operators above.
Spaces are allowed between operands.
The "offset" directive is not allow with in a math symbol. Simply
give the name of the symbol with out the "offset" directive for the
same affect.
Example:
MOV AX,(1+2*3/4|5^6&7>>8<<9) ; 0
MOV AX,(-1+2) ; 1
MOV AX,(-1 + 2) ; 1
MOV AL,(~0 + 1) ; 0 (~0 = -1) (-1 + 1 = 0)
MOV AX,(~1 + 1) ; FFFFh (~1 = FFFEh) (FFFEh + 1 = FFFFh)
MOV AX,(1--1) ; 2
MOV AX,('0' - 48) ; 0
MOV AX,( 100h >> 1 ) ; 80h
MOV EAX,( 100h >> 1 ) ; 80h
MOV EAX,(123456h+123456h) ; 2468ACh
MOV AX,(TEMP+100h) ; TEMP+100h (where TEMP is an EQUate)
MOV AX,(TEMP+100h) ; offset TEMP+100h (where TEMP not an EQUate)
MOV AX,(TEMP-TEMP1) ; offset TEMP - offset TEMP1
JMP SHORT ($+2) ; jump to next instruction
A note about the NOT operator (~) above: When you use the NOT
operator, the whole 32bit value is NOT'ed. Look at the following:
mov al,(0FFh+1) ; returns an error ( 100h won't fit in a byte )
mov al,(~0+1) ; (no error) returns 00h (~0 = -1. -1 + 1 = 0)
******* Please be carefull when using this type of operand.
The whole operand must be enclosed in parenthesis. ()'s
Here is an example of what can confuse you:
temp db (8*3)-1
The above line would look like it would allocate a single
byte and place 23 in this byte.
However, it actually allocates two bytes, placing 24 in the
first, and -1 (0FFh) in the second.
NBASM treats the above line as two different operands, noticing
the '-' as a delimiter for the next operand.
Precedence of each operator. i.e.: an operator higher in the list
takes precedence over an operator below it in the list.
12. MUL (integer) *
11. NEG -
NOT (bitwise) ~
NOT (logical) !
10. POWER **
9. MUL *
DIV /
MOD %
8. ADD +
SUB -
7. SHR >>
SHL <<
6. LT <
GT >
LE <=
GE >=
5. EQ == or = ('=' does not do the same as the C '=')
NE !=
4. AND (bitwise) &
3. OR (bitwise) |
XOR (bitwise) ^
2. AND (logical) &&
OR (logical) ||
1. any remaining items.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 19
Register Operands:
An 8 bit register:
AH, AL, BH, BL, CH, CL, DH, DL
A 16 bit register:
AX, BX, CX, DX, SP, BP, SI, DI
A 32 bit register (32-bit):
EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI
CR0 registers, DR0 registers
A segment register:
CS, SS, DS, ES, FS, GS
(FS and GS are .386+)
Memory Operands:
The contents of a memory location addressed by one of the following
methods. Note that none of the memory addressing options specifies that
whether a byte, word, or a dword operand is being referenced when used
with a register since a register already has a size.
Direct address
A number, or symbol representing a number, enclosed in brackets,
indicating an offset into the data segment.
Example:
Buffer EQU 2222h
MOV BH,[Buffer]
MOV [80h],DI
A symbol defined to be a variable (i.e. a named memory location) using the
EQU pseudo-op.
Example:
CmmdLen EQU [81h]
MOV DI,CmmdLen
A symbol defined to be a variable by its use with a storage defining
pseudo-op.
Example:
MOV AX,FLAG
MOV Pos,BX
FLAG dw 22
Pos dw 22h
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 20
Indirect Address:
The address of the operand is the sum of the contents of the indicated
register(s) and a displacement. The register, or sum of registers, are
enclosed in square brackets: []
The displacement is optional, and takes the form of an immediate operand,
placed without intervening delimiters to the left of the first bracket or
at the end before the last bracket.
Displacements in the range -128 to 127 (hex 00 - 7F, FF80 - FFFF,
FFFFFF80-FFFFFFFF) are interpreted as signed 8 bit quantities. All other
displacements are interpreted as unsigned 16-bit or 32-bit quantities.
Note that although the 8086/88 supports unsigned 16 bit displacements up
to hex FFFFh for indirect addressing, NBASM does not distinguish between
-1 and 0FFFFh. They are both the same value to NBASM.
The following indirect modes are allowed:
Indirect through a base register (BX|BP), index register (SI|DI),
memory operand, immediate, or a combination of operands.
*** Please Note: Currently, the 32 bit indirect addressing using
EBP, ESP, [base32+index32], and any scaling (*1,*2,*4,*8)
may produce unpredictable results.
Examples:
mov al,[bx+1]
mov al,[bx][1]
mov al,[si+1]
mov al,[si][1]
mov ax,[bx][si][-10h]
mov ax,[bx][si-10h]
mov ax,[bx][10h][di]
mov ax,[10h][si][bx]
mov ax,10h[di][bx]
mov ax,+10h[di][bx]
mov ax,-10h[di][bx]
mov ax,-10h+[di][bx]
mov ax,[bp][10h][si]
mov ax,[bp][di][10h]
mov ax,[si][bp][10h]
mov ax,[di][bp][10h][10h]
mov ax,[bx+100h+05h]
mov ax,[bx+0]
mov ax,[bp+1]
mov ax,[bx+1-1]
mov ax,[bx+si]
mov ax,[bx+si+1]
mov ax,[bx+di]
mov ax,[bx+di+1]
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 21
mov ax,[bp+si]
mov ax,[bp+si+1]
mov ax,[bp+di]
mov ax,[bp+di+1]
mov ax,[05h]
mov ax,[100h]
mov ax,[100h+05h]
mov ax,[105h]
mov ax,[memory]
mov ax,[memory+1]
mov ax,[memory+bx]
mov ax,[bx+memory]
mov ax,[bx+memory+1]
mov ax,memory
mov ax,memory[bx]
mov ax,memory[bx+1]
mov ax,memory[bx+0]
mov ax,memory[bx+1]
mov ax,memory[bx+si]
mov ax,memory[bx+si+0]
mov ax,memory[bx+si+1]
mov ax,memory[bx+si+1+1]
Labels
A label on a machine instruction may be used as an operand for call and
jump instructions.
Example:
DoIt PROC NEAR
CALL DoIt
JMP Place
Strings
A string is any sequence of characters (including delimiters) surrounded
by single or double quotes. Note: Empty strings are ignored
Example:
DB 'Forever Young Software'
DB "Copyright 1984-2003"
DB '' ; this is ignored
DB 12,'',30 ; the empty string is ignored
; returns 12,30
Memory references
When one specifies the address of a memory location, it is unclear how
large an operand is being referenced. An operand might be a byte, word,
or a dword. If a register is present as an operand, it is assumed that
the memory operand matches the register in size. Exceptions to this rule
are the shift and rotate instructions, where the CL register is used as a
counter, and has nothing to do with the size of the other operand.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 22
Example:
MOV MASK,AX ;mask is a word
MOV AL,[BX] ;BX points to a byte
AND [SI] ;error, operand of unknown size
SHR MASK,CL ;error, mask is of unknown size
If no register is present, (or if the only register is CL being used as a
counter) the size of the memory operand is specified by adding the suffix
"B", "W", "D", "F", or "Q"; or a type specifier "BYTE", "WORD", "DWORD",
"FWORD", or "QWORD" to the instruction mnemonic.
Examples:
INCB [BX] ;BX points to a byte
INC BYTE [BX] ;BX points to a byte
INCW [BX] ;BX points to a word
INC WORD [BX] ;BX points to a word
INCD [BX] ;BX points to a dword
INC DWORD [BX] ;BX points to a dword
INC DWORD [EBX] ;EBX points to a dword
MOVW TEMP,00H ;TEMP is a word
MOV WORD TEMP,00H
MOVD TEMP,00H ;TEMP is a dword
MOV DWORD TEMP,00H ;TEMP is a dword
MOVB DH,[BX] ;error, register already specifies size
MOVZX ax,byte [bx]
MOVZX byte ax,[bx]
MOVZX eax,byte [bx]
MOVZX byte eax,[bx]
MOVZX eax,word [bx]
MOVZX word eax,[bx]
Indirect Branching
The 8086/88 supports two flavors of indirect branching. Intra, and inter
segment. A register is set to point at a memory location which contains a
new value for the program counter, and in the case of intersegment
branching, a new value for the CS register as well.
Please note: If a type of NEAR or FAR is not specified, NEAR is assumed.
Examples:
CALL [BX] ; intrasegment memory indirect call
CALL [EBX] ; intrasegment memory indirect call
CALLN [BX] ; intrasegment memory indirect call
CALL NEAR [BX] ; intrasegment memory indirect call
CALLF [BX+SI] ; intersegment memory indirect call
CALL FAR [BX] ; intersegment memory indirect call
CALL FAR [EBX] ; intersegment memory indirect call
CALL AX ; intrasegment register indirect call
CALLN DX ; intrasegment register indirect call
JMP [BP+DI] ; intrasegment memory indirect jump
JMPN [BP+DI] ; intrasegment memory indirect jump
JMP NEAR [BP+DI] ; intrasegment memory indirect jump
JMPF [DI+4] ; intersegment memory indirect jump
JMP FAR [DI] ; intersegment memory indirect jump
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 23
JMP CX ; intrasegment register indirect jump
JMPN CX ; intrasegment register indirect jump
JMPS CX ; intrasegment register indirect jump
JMP offset,segment ; jump 'very far' :-)
JMP FAR offset,segment ; jump 'very far'
Please note:
Even though the next two lines assemble, and DEBUG correctly disassembles
them, they would not create correct branching.
CALLF DX ; intersegment register indirect call
JMPF CX ; intersegment register indirect jump
Long and Short Jumps
Two types of relative jumps are supported by the 8086/88:
Short (specified by a signed 8 bit displacement) and
Long (specified by a 16 bit displacement).
Both are implemented in NBASM as a jump to a label.
The short jump is specified by mnemonic JMPS or JMP SHORT. Since one of
the displacement bits is used as a sign bit, only seven bits are left to
express the magnitude of jump. JMPS (and similarly, all the jump on-
condition instructions) is thus limited to branching to labels within a
range of -128 to +127 bytes.
Example: (non conditional)
Start:
JMPS Start ;short jump (2 bytes) (intrasegment)
JMP SHORT Start ;short jump (2 bytes) (intrasegment)
JMPS End ;short jump (2 bytes) (intrasegment)
JMP SHORT ($+2) ;short jump (2 bytes) (intrasegment)
JMP End ;long jump (3 bytes) (intrasegment)
JMP Start ;long jump (3 bytes) (intrasegment)
JMP offset,segment ; jump 'very far' (intersegment)
JMPF offset,segment ; jump 'very far' (intersegment)
JMP FAR offset,segment ; jump 'very far' (intersegment)
If you are using the .386 or higher directive, NBASM will allow a
conditional near jump. A conditional jump that is more than 128 byte
displacement. However, this now uses the four (4) byte instruction
instead of the two (2) byte instruction. If you know that the jump will
be less than 128 bytes in displacement, then include the SHORT directive
on the line.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 24
Example: (conditional)
; where Close is less than 128 bytes away
; and Faraway is more than 128 bytes away
Close:
.286 ; (or lower)
JC Close ; short jump (2 bytes)
JC SHORT Close ; short jump (2 bytes)
JC Faraway ; error, to far
JC SHORT Faraway ; error, to far
.386 ; (or higher)
JC Close ; short jump (4 bytes)
JC SHORT Close ; short jump (2 bytes)
JC Faraway ; near jump (4 bytes)
JC SHORT Faraway ; error, to far
.
.
.
Faraway:
Instruction Prefixes.
The 8086/88 supports three instruction type prefixes:
Segment override
An alternate segment register is specified for a reference to memory.
(CS:, DS:, ES:, SS:, FS:, or GS:)
Repeat
REP, REPE, REPNE, REPZ, REPNZ
A string primitive is repeated until a condition is met.
LOCK
Turns on the LOCK signal. Only useful in multiprocessor situations
(8086/88 and 8087 for example).
NBASM implements these prefixes as separate instructions, rather than
prefixes to another instruction. Some must appear on the same line
while others on a separate line, immediately before the operand they
modify.
Example:
ES: ;
MOV AX,FLAG ; flag is in the extra segment
MOV AX,ES:FLAG ; this line is the same as the two above
REP ; must appear on a separate line just above
MOVSB ; move bytes until CX decrements to 0
Pseudo-Operations
The following pseudo-ops are implemented:
$: This location
The '$' symbol can be used as an operand to find the offset of a
position relative to the start of the segment.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 25
Example: (code segment)
mov ax,$
mov ThisLoc,ax ; ThisLoc = offset of POS in segment
ThisLoc equ $
Example: (data segment)
ThisPos dw $
ThisPos db $ ; returns an error. $ is sizeof word
?: Undefined Data
The '?' denotes undefined data in a DUP line. (see below)
However, if you use the '?' symbol else where, NBASM places an
undefined value in its place as the size noted.
Example:
mov ax,? is the same as mov ax,xxxxh
mov al,? is the same as mov al,xxh
TEMP DB ? is the same as TEMP DB xxh
TEMP DW ? is the same as TEMP DW xxxxh
DB: Declare Byte(s)
Memory locations are filled with values from the operand list. Any
number of operands may appear (up to the line length limit), but all
must fit on one line. Acceptable operands are numbers between 00h and
0FFh (0-255 decimal), or strings enclosed in single or double quotes.
You can use any ascii char from 00d to 255d except 0, 9, 10, and 13.
If you need to use one of these chars, you must give the ascii value
instead of the literal char.
If a label appears, it is considered a variable, and the location may
be referred to using the label, rather than an address. The reason
for the use of single or double quote is so that you can put a single
quote as a char in a string delimited by a double quote and vise-
versa.
Example:
MASK DB 00h,01h,02h,03h
Strg1 DB 'A string'
Strg2 DB "A string"
DB "A string's single quote"
DB 'Can NOT use ascii char 13d. Ascii 13d =',13
Strg5 DB ?,? ; declares two undefined bytes
DD: Declare double word(s)
Identical to DW (below) except uses dwords instead of words, and does
not allow strings as DB and DW does. Use a range of 0 and 0FFFFFFFFh
Example:
Val5 DD ? ; declares an undefined dword
DD offset Strg5 ; 0000xxxxh
DD 12345678h
DD 'Not allowed and will return an error'
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 26
DF: Declare Far word(s)
Identical to DF (below) except uses far words instead of words, and
does not allow strings as DB and DW does. Use a range of 0 and
0FFFFFFh. (i.e.: 3 bytes)
Example:
Val5 DF ? ; declares an undefined fword
DF offset Strg5 ; 00xxxxh
DF 123456h
DF 'Not allowed and will return an error'
DW: Declare word(s)
Identical to DB (above) except uses words instead of bytes. Use a
range of 0 and 0FFFFh (0-65535 decimal)
Example:
Val5 DW ?,? ; declares two undefined words
DW offset Strg5
DW 1234h
DW 'Allowed and will NOT return an error'
DUP: Declare Storage (Initialized data)
Used to declare large blocks of identically initialized storage. The
first operand is required, a number specifying how many bytes are
declared. If a second operand in the form of a number 00h-FFh
appears, the locations will all be initialized to this value. If the
second operand is not present, locations are initialized to 00h.
As with DB, any label is considered a variable. To save space, the
object code does not appear on the listing.
Example:
DUP 22 ; 22 locations initialized to 00h
DUP 100h,22h ; 256 locations initialized to 22h
TEMP DUP 22 ; 22 locations initialized to 00 and
; pointed to by TEMP
DUP 0 ; error: 55h
DUP: Declare Storage (Uninitialized data)
This is the same as the 'initialized data' above except that it doesn't
write anything to the executable file. You can specify uninitialized
data at the end of your .com files this way. However, if you specify
any other data or code that is not uninitialized data after an
'uninitialize data' line, NBASM will give an error of 5Ch.
Example:
TEMP DUP 10,? ; Uninitialize data. This only increments the 'IP'
; position. Doesn't write to the COM file.
; (see page 54 for more info on .OBJ files)
If you use any .external procedures in your .COM file, any undeclared
data will be overwritten with the external code
I plan to add some code and documentation to NBASM to allow the coder
to find where the end of any external code will be. Until then, be
careful about assuming where the code is and how long it is.
ENDP: End of Procedure
See PROC (below) for details.
EQU: Equate
Used to equate a symbolic name with a number. The symbol may then be
used anywhere the number would be used. Use of symbols makes programs
more understandable, and simplifies modification.
An alternate form of EQU encloses the number in square brackets: [].
The symbol is then interpreted as a variable, and may be used as an
address for memory access. This version is provided to allow symbolic
reference to locations outside the program segment.
Warning: Difficult to debug errors may result from using a symbol
prior to its being defined by EQU. All Equates should be defined at
the beginning of the code.
Warning: You may get a "phase error between passes" error if you
use an EQUate symbol before you define it. If so, define the EQUate
symbol before you use it.
Example:
MOFFSET EQU B000H
MONOCHROME EQU [0000H]
LENGTH EQU (var2-var1) ; bytes between var1 and var2
LENGTH EQU ($-TEMP1) ; Current Location - offset TEMP1
HIGH or HIGHB: Return the high byte of an expression.
Returns the high byte of the next operation:
if the value is greater than 65535, it will return the high word.
HIGHB will return the high byte either way
Example:
mov al,high 1234h = mov al,12h
mov al,high offset var = mov al,(high byte of offset)
mov ax,high 1234h = mov ax,12h
mov eax,high 1234h = mov eax,12h
mov ax,high 1234h = mov ax,12h
mov ax,highb 12345678h = mov ax,12h
mov ax,high 12345678h = mov ax,1234h
Remember that you can not use this operator on variables.
For Example:
mov al,high var
will return the high byte of the OFFSET of var, NOT the value of var.
(also see LOW)
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 27
INCLUDE: Include a file
NBASM supports include files nested up to 10 max. An include file can
have any name and extension. The file can contain most anything that
a main module would. If you use an include statement and file, and this
you included file contains any executable code, you must put this
include file after any of the following directives:
.model, .stack, .186 (or similar), and .start
Syntax for the include statement is:
(The INCLUDE statement must start in column one as a label would)
INCLUDE filename.inc
NBASM searches for the include file in the following order:
1. NBASM uses the directory specified with the /I{} parameter
if it is specified on the command line.
2. NBASM searches the path specified by the command line.
e.g.:
If you use the following command line:
NBASM demo
then NBASM searches the current directory for the include file.
If you use the following command line:
NBASM C:\source\demo
then NBASM searches the C:\SOURCE directory for the include file.
3. NBASM searches the directory that is pointed to by your INCLUDE=
parameter in the ENVIRONMENT.
You can use the /I{} parameter at the command line to tell NBASM what
path to look in for the include file. If you use this /I{} parameter,
then NBASM does not look in the dir(s) pointed to by the
INCLUDE=environment variable.
Example:
NBASM demo.asm /i{c:\includes}
This will tell NBASM that the include file is in the directory:
c:\includes\
An included can be of any size and must end with the .end directive.
NBASM will still assemble the file(s) correctly, but will return an
error if the .end directive is not used in the include file(s).
NBASM will not allow including an already nested include file.
LOW or LOWB: Return the low byte of an expression
Returns the low byte of the next operation:
if the value is a 32-bit value, it will return the low word.
LOWB will return the low byte either way
Example:
mov al,low 1234h = mov al,34h
mov al,low offset var = mov al,(low byte of offset)
mov ax,low 1234h = mov ax,34h
mov eax,low 1234h = mov eax,34h
mov ax,low 1234h = mov ax,34h
mov ax,lowb 12345678h = mov ax,34h
mov ax,low 12345678h = mov ax,5678h
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 28
Remember that you can not use this operator on variables.
For example:
mov al,low var
will return the low byte of the OFFSET of var, NOT the value of var.
(also see HIGH)
ORG: Origin
Allows direct manipulation of the location counter during assembly.
By default, NBASM assembles code to start at offset 100h, the origin
expected by COMMAND.COM for .COM programs. By using ORG, you may
override this default.
Example:
ORG 0 ; Code will be assembled for starting offset of 00h
ORGNF: Origin No Fill
This does exactly what ORG does above, except it does not
place any filler bytes in the file if moving forward.
Also, ORGNF will allow any offset even if it is a reverse
from the current position. ORG will only allow forward
offsets.
Example:
ORGNF 200h ; Code will be assembled for starting offset of 200h
; but no filler bytes will be placed at the start
; of the file. ORG above would place 100h filler
; bytes at the start of the file.
PROC ...ENDP: Procedure Definition
Declares a procedure. One operand is required on PROC, either the
word NEAR, or the word FAR. This pseudo-op warns NBASM whether to
assemble returns as intra (near) or intersegment (far). Procedures
called from within your program should be declared NEAR.
ENDP terminates the procedure, and requires no operands.
Procedures can not be nested.
The label is not required on the ENDP line but if one is, it must
match the label on the PROC line.
The word USES may follow the NEAR|FAR word to tell NBASM to save the
specified registers listed after the word USES.
Example:
MAIN PROC NEAR USES AX BX SI
...
...
RET
MAIN ENDP ; the label 'MAIN' is not required here
This example will declare a near procedure and save the following
registers: AX, BX, and SI
Then NBASM will restore these registers just before the RET is
encountered. (or a .NORET directive is encountered. See .NORET
for more information)
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 29
If you do not place a RET with in your PROC/ENDP block, NBASM will
return an error. See the .NORET directive for more information if
you do not what a RET inside your PROC/ENDP block.
You can use the ALL and ALLF keywords. The ALL keyword is the same as
if you used PUSHA/POPA (186+) and the ALLF keyword is as if you used
PUSHA/POPA and PUSHF/POPF.
Please Note: Saves only the registers PUSHA saves and requires .186+
You can also use the ALLD and ALLDF keywords. The ALLD keyword is the
same as if you used PUSHAD/POPAD (386+) and the ALLDF keyword is as if
you used PUSHAD/POPAD and PUSHFD/POPFD.
Please Note: Saves only the registers PUSHAD saves and requires .386+
MAIN PROC NEAR USES ALL ; save all registers (Pusha)
or
MAIN PROC NEAR USES ALL ds ; save all registers and ds
or
MAIN PROC NEAR USES ALLF ; save all registers and the flags
or
MAIN PROC NEAR USES ALLD ; save all registers (Pushad)
or
MAIN PROC NEAR USES ALLDF ; save all 32 bit regs and eflags
Note: See the documentation for PUSHA(D)/POPA(D) for the registers
ALL(D) uses.
If a RET is encountered outside of a declared procedure in a .COM
file, NBASM will put the opcode value of 0C3h (ret) so that you can
exit with one byte. If this happens in an .OBJ (.model small) file or
if the .start directive is used, and error will be given.
SIZEOF: get sizeof type
Return the size of a specified type.
See page 53 for more information.
ST: Structure Declaration
Declare a symbol of type struct predefined structure type declaration.
See page 51 for more information.
Directives
.8086
Enables usage 8086 instructions (default)
(for returning to 8086 after .186, .286, etc.)
.186
Same as .8086 above and allows 80186 instructions
.286
Enables all non-privileged instructions up to the 80286
.286P
Same as .286 above and allows all 80286 privileged instructions
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 30
.386
Enables all non-privileged instructions up to the 80386
.386P
Same as .386 above and allows all 80386 privileged instructions
.486
Enables all instructions up to the 80486 including all privileged
286/386 instructions.
.586
Enables all instructions up to the 80586 (Pentium) including all
privileged 286/386 instructions.
Please note: Some of the instructions that NBASM allows with this
directive are use for a Pentium Pro or Pentium II/III.
.87
Enables usage 8087 instructions
(for returning to 8087 after .187, etc.)
.187
Same as .87 above and allows 80187 instructions.
(Please note: Will give error if not in .186+ mode)
.287
Same as .187 above and allows 80287 instructions.
(Please note: Will give error if not in .286+ mode)
.387
Same as .287 above and allows 80387 instructions.
(Please note: Will give error if not in .386+ mode)
.ADSIZE
Places a single byte (67h) into the code
.ALIGN xx ; 2 <= xx <= 4096
Aligns the next statement/data on a 'xx' boundary. Pads with a NOP
if necessary.
.ALPHA
Tell NBASM to write the segments in alphabetical order. Used only in
OBJ files. If in a COM file, it is ignored.
.CODE
Specifies that all that follows will be put in the code segment until
a .DATA or .END is reached. The .CODE directive must be in both
types of output files and before any actual code statements.
.DATA
Specifies that all that follows will be put in the data segment until
a .CODE or .END is reached. The .DATA directive can not be in a COM
file (.model tiny (see below)).
.DOSSEG
Specifies to the assembler to include all segments in this order:
CODE (DGROUP), DATA, BSS, STACK (default)
.END
Specifies to NBASM that end of file was reached. Any text after the
.end directive will be ignored. The .end directive must be used for
each source file.
.EVEN
Aligns the next statement/data on a word boundary. Pads with a NOP
if necessary.
.EXIT
System Macro. Simply places the 'Exit to DOS' code in your file:
mov ah,4Ch
int 21h
If you specify an 8 bit value in the form of an immediate or a single
quoted char, then NBASM will use this value as the AL portion of the
code (the RC/ERRORLEVEL), else the AL register will be assumed:
.exit 01h = mov ax,4C01h
.exit 22 = mov ax,4C16h
.exit 'A' = mov ax,4C41h
.exit = mov ah,4Ch
.EXTERNAL symbol1, symbol2, symbol3, ...
Specifies that the following symbol(s) is/are external.
COM files:
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 31
If .external is used in the TINY model (see below), then NBASM
loads the correct library and adds the code to the end of the .COM
file for these external procedures. Please see 'Using the Library'
for more info on calling external procedures in .com files.
Note: If a symbol is declared external via .external but is not
used in the code, NBASM will NOT add the associated code to the end
of the .com file.
Note: If the external procedure used is of a higher processor type
than what has been currently declared, then an error will be
returned.
If you use any .external procedures, any undeclared data will be
overwritten with the external code (see DUP)
EXE files: (Currently not supported)
(see page 54 for more info)
.IF/.ELSE/.ENDIF and .IFDEF/.IFNDEF
NBASM allows conditional assembling. It is very easy to use. Simply
include an immed7/8/16/32 as the parameter in the form of a literal
constant, math equation, or as an EQUate.
If the value given is 0 (false), the following code is not assembled
until an .ELSE or an .ENDIF statement is found.
If the value is not 0 (true), then the code is assembled until an
.ELSE or an .ENDIF statement is found. If an .ELSE statement is
found, then the rest of the code is not assembled until the .ENDIF
statement is found. When the .ENDIF is found, assembly continues as
normal.
.IFDEF returns TRUE (1) if the symbol used has been defined with
the EQU operator.
.IFNDEF returns TRUE (1) if the symbol used has *NOT* been defined
with the EQU operator.
Debug EQU 00h ; (false)
.IF Debug
; do NOT assemble this code
.ELSE
; DO assemble this code
.ENDIF
.IF Debug
; do NOT assemble this code
.ENDIF
.IF 1 ; one is considered not zero, not false.
; DO assemble this code
.ELSE
; do NOT assemble this code
.ENDIF
.IFDEF Debug
; DO assemble this code
.ENDIF
.IFNDEF Debug
; do NOT assemble this code
.ENDIF
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 32
Please note that the .IF/.ELSE/.ENDIF conditional assembler directives
can NOT be nested, and that NBASM does not check for a valid
.IF/.ELSE/.ENDIF block. If it isn't a valid .IF/.ELSE/.ENDIF block,
unexpected errors could happen.
.JUMPS (currently not working correctly) (* DO NOT USE *)
Tells NBASM to substitute a JNcc $+3 and a JMP label for a short
conditional jump that is to far away.
Example:
jz short There ; ** one byte to far **
dup 128,0 ; can be any code or data
There:
Gets replaced with:
jnz short Here ; (jnz $+3)
jmp There
Here: dup 128,0 ; can be any code or data
There: ; *But why would you jump to data?*
You can also use the /J on the command line instead of this directive.
Both are the same and both can be used together with no error.
.LIST (0 or not(0))
Tells NBASM to stop/start sending data to the .lst file. A value of
00h means stop, a non 00h value means start.
If the /X parameter was not used on the command line, the .LIST
directive is ignored.
By default, NBASM sends data to the .lst file if /X was found on the
command line. The .LIST directive is not needed to start the .lst
file.
.LIST 0 ; stop sending things to the .lst file
.LIST 1 ; start sending things to the .lst file
.MODEL (TINY or SMALL)
Defines the output file as either a COM file or an OBJ file. If no
.model directive is encountered, NBASM returns and error.
** The .model directive must be before all (most) other directives. **
Example:
.MODEL TINY ; declares a COM file for output
.MODEL SMALL ; declares an OBJ file for output in the small model
.NORET (no return)
Since NBASM returns an error if you do not use a RET inside your
PROC/ENDP block, you might want to use .NORET. This directive
does exactly what a RET would do, except the actual opcode for
RET is not added to your code. Use this directive when you want
to use the USES directive so that the stack will remain clean.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 33
.OPSIZE
Places a single byte (66h) into the code
.OPTOFF
Turns the optimizer off
.OPTON
Turns the optimizer on
.PAGE
Aligns the next statement/data on a pape boundary (512 bytes).
Pads with NOP's if necessary.
.PARA
Aligns the next statement/data on a paragraph boundary (16 bytes)
Pads with NOP's if necessary.
.STACK
Specifies the amount to reserve for the stack. If an operand is not
specified, then 256 is assumed. If an operand is specified, it must
be in the range of 64 - 65534, and tells NBASM to assign that many
bytes for the stack. (NBASM will increment to next even number if
needed)
.STACK ; default 256 bytes
.STACK 128 ; use 128 bytes
.STACK 127 ; use 128 bytes
.START
Specifies to NBASM to do the startup code. This directive must be
before any other code, but it is not required by NBASM to assemble.
In the TINY model (COM), this directive calculates the amount of
memory that the program needs, adds the stack size, (given by the
.stack directive or 256 if .stack not used), and resizes the memory
block to this size. Then the .start directive points SP to the top
of this block.
If you use this directive in a COM file, you can not use the RET
instruction to exit to DOS because SP doesn't point to offset 0FFFEh
anymore. i.e.: [SP] is not guaranteed to be 00h, and doesn't point
to the INT 20h vector in the PSP.
If you use the optimizer option and the .start directive, NBASM will
not change INT 20h to RET.
In the SMALL model (OBJ), this directive processes the segment
addressing parameters ('puts the correct values in the segment
registers') as well as to free the unused memory blocks. If this
directive is not used in the SMALL model, you will have to write your
own startup code, and segment addressing.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 34
Example:
.START ; that's it, nothing else needed.
If you don't want to use the .START directive, use the following in
your '.model small' files (see macro section at end of this file):
mov ax,%data
mov ds,ax
mov es,ax
.x86
Allows all instructions to be assembled
Memory References
To access memory outside the program segment, you simply move a new
segment address into the DS register, then address using offsets in the
new segment. The memory option of the EQU pseudo-op allows you to give a
variable name to offsets in other segments. For example, to access the
graphics character table in ROM:
BIOS EQU F000H
CHARTABLE EQU [FA6EH]
MOV AX,BIOS ; can't move immed. to DS
MOV DS,AX
MOV AL,CHARTABLE ; 1st byte of char table
Code Branching
NBASM supports 4 instructions for branching outside the program segment.
Direct CALL and JMP
New values for the IP and CS registers are included in the instruction
as two immediate operands.
Example: (real mode)
SEGMENT1 EQU 01234h
OFFSET1 EQU 05678h
JMP Offset1,Segment1
Example: (pmode)
jmp far offset32,descriptor16
*** Remember that the offset is the first operand, and the segment is the
second operand.
In RMODE, the JMP FAR and CALL FAR instructions create the following
opcode:
9Ah, 16-bit offset, 16-bit descriptor
In PMODE, the JMP FAR and CALL FAR instructions create the following
opcode:
9Ah, 32-bit offset, 16-bit descriptor
Indirect CALLF/CALL FAR and JMPF/JMP FAR (real mode)
Four consecutive bytes in memory are initialized with new values for
the IP and CS registers. The CALLF or JMPF then references the
address of the new values.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 35
Example:
MOV [DI],Offset1
MOV [DI+2],Segment1
CALLF [DI]
CALL FAR [DI]
SEGMENT1 DW 1234h
OFFSET1 DW 5678h
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 36
Instructions
The following list is a list of all mnemonics that are allowed with NBASM
and a short description. In the column before the mnemonics is the lowest
allowed processor. If it is blank, then an 8086/88 is assumed. (186+ =
80186 or better, etc)
If you know of any 586 or less mnemonic/instruction not listed here, please
let me know. (I am sure I am missing a few.)
(Please see notes on FPU instructions below)
AAA - Adjust after BCD addition
AAD - Adjust before BCD division
AAM - Adjust before BCD multiplication
AAS - Adjust after BCD subtraction
ADC - Arithmetic addition with carry
ADCB - (byte)
ADCD - (dword)
ADCW - (word)
ADD - Arithmetic addition
ADDB - (byte)
ADDD - (dword)
ADDW - (word)
AND - Logical AND
ANDB - (byte)
ANDD - (dword)
ANDW - (word)
286+ ARPL - Adjust RPL field or segment selector
386+ BSF - Bit scan forward
386+ BSR - Bit scan reverse
486+ BSWAP - 32bit reg from little-endian -> big-endian
386+ BT - Bit test
386+ BTC - Bit test and complement
386+ BTR - Bit test and reset
386+ BTS - Bit test and set
CALL - Call Procedure
CALLF - (far)
CALLN - (near)
CBW - convert signed byte (AL) to word (AX)
386+ CDQ - convert signed dword (EAX) to dword pair (EDX:EAX)
CLC - Clear carry
CLD - Clear direction flag
CLI - Clear Interrupt flag
386+ CLTS - Clear Task-Switched Flag in CR0
CMC - Complement the carry flag
686+ CMOVcc - Conditional MOV reg, reg/mem
(please note that currently NBASM does not have a .686 (Pentium
Pro) directive. Use the .586 directive)
CMP - Compare
CMPB - (byte)
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 37
CMPD - (dword)
CMPSB - Compare String Byte
CMPSW - Compare String Word
CMPW - (word)
586+ CMPX8B - Compare and exchange 8 bytes
486+ CMPXCHG - Compare and exchange
486+ CPUID - Return CPU ID using EAX in EDX:EAX
CWD - convert signed word (AX) to word pair (DX:AX)
386+ CWDE - convert signed word (AX) to dword (EAX)
DAA - Adjust after addition
DAS - Adjust after subtraction
DEC - Decrement
DECB - (byte)
DECD - (dword)
DECW - (word)
DIV - Unsigned divide
ENTER -
F2XM1 -
FABS -
FCHS -
387 FCOS -
FDECSTP -
FINCSTP -
FLD1 -
FLDL2E -
FLDL2T -
FLDLG2 -
FLDLN2 -
FLDPI -
FLDZ -
FNOP -
FPATAN -
FPREM -
387 FPREM1 -
FPTAN -
FRNDINT -
FSCALE -
387 FSIN -
387 FSINCOS -
FSQRT -
FTST -
FWAIT - wait for coprocessor to finish
FXAM -
FXTRACT -
FYL2X -
FYL2XP1 -
HLT - wait for an interrupt
ICEBP - Interrupt trap to debugger (interrupt 1) ** Undocumented **
IDIV - Signed divide
IMUL - Signed integer multiplication
386+ IMUL - (reg16,reg/mem)
186+ IMUL - Signed integer multiplication (reg16,immd8)
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 38
186+ IMUL - Signed integer multiplication (reg16,immd16)
IN - Get AL/AX/EAX from port (DX)
(DX is used if any other 16 bit register is supplied)
INC - Increment
INCB - (byte)
INCD - (dword)
INCW - (word)
186+ INSB - In String Byte (AL)
386+ INSD - In String DWord (EAX)
186+ INSW - In String Word (AX)
INT - Software interrupt
INT3 - Interrupt trap to debugger (interrupt 3)
INTO - Interrupt on Overflow
486+ INVD - Invalidate Internal Caches
486+ INVLPG - Invalidate TLB Entry
IRET - Return from interrupt
386+ IRETD - Return from interrupt (32 bit)
JA - Jump if above (CF=0, ZF=0)
JAE - Jump if above or equal (CF=0)
JB - Jump if below (CF=1)
JBE - Jump if below or equal (CF=1, ZF=1)
JC - Jump if carry (CF=1)
JCXZ - Jump if CX = 0
JE - Jump if equal (ZF=1)
JG - Jump if greater than (ZF=0 or SF=OF)
JGE - Jump if greater than (ZF=OF)
JL - Jump if less than (ZF!=OF)
JLE - Jump if less than or equal (ZF=1 or ZF!=OF)
JMP - Unconditional Jump
JMPF - (far)
JMPN - (near) (same as JMP above)
JMPS - (short)
JNB - Jump if not below (CF=0)
JNC - Jump if no carry (CF=0)
JNE - Jump if not equal (ZF=0)
JNO - Jump if no OverFlow (OF=0)
JNP - Jump if no Parity (PF=0)
JNS - Jump if no Sign (SF=0)
JNZ - Jump if no Zero (ZF=0)
JO - Jump if overflow (OF=1)
JP - Jump if Parity (PF=1)
JPE - Jump if Parity Even (PF=1)
JPO - Jump if Parity Odd (PF=0)
JS - Jump if Sign (SF=1)
JZ - Jump if Zero (ZF=1)
LAHF - Load into AH lower byte of flags
386+ LAR - Load access rights
LDS - Load DS segment offset of
LEA - Load affective address
186+ LEAVE - Leave
386+ LEAVED - Leave (32 bit)
LES - Load ES segment offset of
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 39
386+ LFS - Load FS segment offset of
386P+ LGDT - Load Global Desc Table Register (LGDT FAR [...])
386+ LGS - Load GS segment offset of
386P+ LIDT - Load Interrupt Desc Table Register (LIDT FAR [...])
386P+ LLDT - Load Local Desc Table Register (LLDT WORD [...])
286P+ LMSW - Move CR0 (machine status word)
286 LOADALL - Load all registers from 0:0800h (opcode: 0Fh 05h)
3/486 LOADALL - Load all registers es:edi (opcode: 0Fh 07h)
LOCK - Lock out other processors until finished
LODSB - Lode String Byte (AL)
386+ LODSD - Lode String DWord (EAX)
LODSW - Lode String Word (AX)
LOOP - Loop until CX = 0
LOOPE - Loop with equal (CX >0 and ZF=1)
LOOPNE - Loop with not equal (CX >0 and ZF=0)
LOOPNZ - Loop while CX >0 and ZF=0
LOOPZ - Loop while CX >0 and ZF=1
386+ LSL - Load segment limit
386+ LSS - Load SS segment offset of
MOV - Move right operand into left operand
MOVB - (byte)
MOVD - (dword)
MOVSB - Move String Byte
386+ MOVSD - Move String DWord
MOVSW - Move String Word
386+ MOVSX - Move and sign extend
386+ MOVZX - Move and zero extend
MOVW - (word)
MUL - Unsigned Multiplication (mul reg8/16)
MULB - Unsigned Multiplication (mul byte [xxxx])
MULW - Unsigned Multiplication (mul word [xxxx])
NEG - Negate (two's complement; multiply by -1)
NEGB - (byte)
NEGD - (dword)
NEGW - (word)
NOP - No Operation
NOT - Logical NOT (one's complement)
NOTB - (byte)
NOTD - (dword)
NOTW - (word)
OR - Logical OR
ORB - (byte)
ORD - (dword)
ORW - (word)
OUT - Send AL/AX/EAX to port (DX)
(DX is used if any 16 bit register is used)
186+ OUTSB - Out String Byte (AL)
386+ OUTSD - Out String DWord (EAX)
186+ OUTSW - Out String Word (AX)
POP - Pop top of stack into operand; inc SP by 2 (pop (e)ax)
186+ POPA - Pop all general registers (DI SI BP SP BX DX CX AX)
386+ POPAD - Pop all extended registers (EDI ESI EBP ESP EBX EDX ECX EAX)
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 40
POPD - Pop top of stack into operand; inc SP by 4
(pop dword [bx] or pop dword tempvar)
POPF - Pop top of stack into flags reg; inc SP by 2
386+ POPFD - Pop top of stack into extended flags reg; inc SP by 4
POPW - Pop top of stack into operand; inc SP by 2
(pop word [bx] or pop word tempvar)
PUSH - Push operand on to top of stack; dec SP by [2|4]
(push (e)ax)
186+ PUSH - Push Immed7 CONST on to top of stack; dec SP by 2
If you use PUSH BYTE 7Fh, what gets pushed is 007Fh.
If you use PUSH BYTE 80h, what gets pushed is FF80h.
The PUSH BYTE instruction is SIGNED.
immed7's are FF80h (-128d) to 007Fh (127d)
186+ PUSH - Push Immed8/16 on to top of stack; dec SP by 2
(push 1234h or push offset tempstr)
186+ PUSHA - Push all general registers (AX CX DX BX SP BP SI DI)
386+ PUSHAD - Push all extended registers (EAX ECX EDX EBX ESP EBP ESI EDI)
PUSHB - Push operand on to top of stack; dec SP by 2
(push immed that is a byte)
PUSHD - Push immed32 on to top of stack; dec SP by 4
(push dword 01h or push dword 1234h)
PUSHD - Push operand on to top of stack; dec SP by 4
(push dword [bx] or push dword tempvar)
PUSHF - Push Flags onto top of stack; dec SP by 2
386+ PUSHFD - Push Extended Flags onto top of stack; dec SP by 4
PUSHW - Push operand on to top of stack; dec SP by 2
(push word [bx] or push word tempvar)
RCL - Rotate left with carry
RCLB - (byte)
RCLD - (dword)
RCLW - (word)
RCR - Rotate right with carry
RCRB - (byte)
RCRD - (dword)
RCRW - (word)
586+ RDMSR -
586+ RDPMC - Read Performance Monitoring Counters (Pentium Pro+)
586+ RDTSC - Read Real Time Clock Stamp
REP - Repeat (used with STOS)
REPE - Repeat while equal (used with STOS)
REPNE - Repeat while not equal (used with STOS)
REPNZ - Repeat while not zero (used with STOS)
REPZ - Repeat while zero (used with STOS)
RET - Return from procedure
ROL - Rotate Left
ROLB - (byte)
ROLD - (dword)
ROLW - (word)
ROR - Rotate Right
RORB - (byte)
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 41
RORD - (dword)
RORW - (word)
586+ RSM -
SAHF - Restore from AH to lower byte of flags
SAL - Shift Left (Adjust) (signed numbers)
SALB - (byte)
SALD - (dword)
SALC - *Undocumented* opcode (see Appendix A)
SALW - (word)
SAR - Shift Right (Adjust) (signed numbers)
SARB - (byte)
SARD - (dword)
SARW - (word)
SBB - Arithmetic subtraction with borrow
SBBB - (byte)
SBBD - (dword)
SBBW - (word)
SCASB - Scan String Byte
386+ SCASD - Scan String DWord
SCASW - Scan String Word
386+ SETcc - SET byte on condition of flags
386P+ SGDT - Store Global Desc Table Register
SHL - Shift Left
SHLB - (byte)
SHLD - (dword) (see note ;';';';
SHLD - (double precision)
SHLW - (word)
SHR - Shift Right
SHRB - (byte)
SHRD - (dword)
SHRD - (double precision)
SHRW - (word)
386P+ SIDT - Store Interrupt Desc Table Register
386P+ SLDT - Store Local Desc Table Register
286P+ SMSW - Move CR0 (machine status word)
STC - Set carry flag
STD - Set direction flag
STI - Set interrupt flag
STOSB - Store String Byte
386+ STOSD - Store String DWord
STOSW - Store String Word
386+ STR - Store task register
SUB - Arithmetic subtraction
SUBB - (byte)
SUBD - (dword)
SUBW - (word)
TEST - Same as AND but neither operands are changed
TESTB - (byte)
386+ TESTD - (dword)
TESTW - (word)
??? UD2 - Undefined Opcode instruction
386+ UMOV - *Undocumented* opcode (see Appendix A)
386+ VERR - Verify for reading
386+ VERW - Verify for writing
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 42
WAIT - wait for coprocessor to finish
486+ WBINVD - Write Back and INValiDate cache
586+ WRMSR - Write to Model Specific Register
486+ XADD - Exchange and add
XCHG - Exchange operands
XLAT - Translate from table (BX=address, AL=offset from 0 (1st))
XLATB - Translate from table (BX=address, AL=offset from 0 (1st))
(use XLAT cs:[BX] when you need an override)
XOR - Exclusive OR
XORB - (byte)
XORD - (dword)
XORW - (word)
FPU instructions
Some other assemblers include an [F]WAIT instruction before the actual FPU
instruction if the processor directive is less than a .286 directive.
Currently, NBASM does not prefix the [F]WAIT instruction. It is up to the
user to prefix this instruction if s/he thinks it is needed.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 43
Miscellaneous Items
Errors
NBASM will return any errors to the screen in the following format:
(see below for errors not returned in this format)
filename.[asm|inc](line number): error number: short description
Symbol space free: amount of byte(s) free
Error(s) detected: number of errors
Diagnostic(s) offered: number of 'D' errors
filename.asm is the source file that NBASM found the error. This is usually
the initial source file. However, if you have included files, this could
be one of the include filenames.
(linenumber) is the line number of the 'filename.asm' that NBASM found the
error.
error number is the number of the error found.
short description is just that (see below for a detailed description).
Symbol space free will display the amount of bytes left in the symbol
table.
Error(s) detected is the number of critical errors.
Diagnostic(s) offered is the number of items that could be changed to make
the source 'better'. Most of the time it will say things like:
'Use short jmp' - use short rather than long
See Running NBASM for errors returned in ERRORLEVEL
Detailed description of assemble time errors:
0Ah = 'Error opening Lib File'
NBASM can not find the library file wanted. The lib file should either be
in the current directory or pointed to by the LIB= environment string
0Bh = 'Error reading from Lib File'
The wanted library file is either corrupt or not a valid NBASM lib file.
0Ch = 'Include file not found'
The specified included file could not be found. The inc file should either
be in the current directory, pointed to by the INCLUDE= environment
string, or specified with the /I{} command line parameter.
0Dh = 'Include filename needed'
Specify a filename after the include keyword
0Eh-11h not specified
12h = 'Unexpected end of line'
Most of the time, NBASM has found a string that doesn't have the closing
mark of a single or double quote.
13h-17h not specified
18h = 'End of file before .END'
All source files, including include files need to have a line with the
.end as the last assembled line.
19h not specified
1Ah = 'Segment near (or at) 64k limit'
Most of the time this means you are trying to create a .COM file that is
larger than 64k, or in the .OBJ model, either your code or your data
segment is reaching the 64k limit
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 44
1Bh = 'Block nesting error'
Used with in INCLUDE file nesting. You can only have ten (10) include
files nested at once.
1Ch-1Dh not specified
1Eh = 'Redefinition of symbol'
You have a symbol with the same name as a previously defined symbol.
Remember that all NBASM symbols are NOT case sensitive.
1Fh not specified
20h = 'Phase error between passes (+|-difference)'
(prints this message on the first occurrence only)
21h = 'Symbol not defined'
NBASM has found a symbol that you have not defined. Check your spelling of
the symbol
22h = 'Syntax error'
Is a general syntax error.
23h = 'Type illegal in context'
You have tried to use an operand that is either the wrong size or most
likely the wrong type.
24h-27h not specified
28h = 'forward reference illegal'
You have used a forward reference in an EQUate line. All EQUates must be
constant or previously declared symbols.
29h-2Dh not specified
28h = 'operand expected'
2Fh-35h not specified
36h = 'only one operand allowed'
You have tried to put too many symbols in an expression.
37h not specified
38h = 'operand expected'
39h-41h not specified
42h = 'improper operand type'
Mostly used in DB and DW lines.
43h = 'jump out of range by ????? bytes'
Specifies that you have used a short jump where a long one is needed.
44h-52h not specified
53h = 'for use in .COM files only'
54h = 'forward reference needs override or far'
Used with PROC FAR
55h = 'illegal value for DUP count'
Supply a smaller dup count
56h not specified
57h = 'PROC nesting too deep'
Only ten (10) nesting levels
58h-59h not specified
5Ah = '.START must be at 100h for .COM files'
.start must be before any other instructions
5Bh not specified
5Ch = 'Undefined DUP used before this location'
You have used an Undefined DUP ( dup count,? ) line before this location
and the data is not in phase
5Dh-5Fh not specified
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 45
60h = 'wrong length for override value'
Most likely used the wrong segment register
61h not specified
62h = 'Forward direction only'
Only use a forward direction with ORG
63h-69h not specified
6Ah = 'Open PROC (needed ENDP)'
Need to supply an ENDP with every PROC
6Bh-72h not specified
73h = 'Too many user symbols (1100 max (13 bytes each))'
You have used up the symbol space.
74h = 'Diagnostic: Specify (d)word or byte operation'
Need size: Byte or Word or Dword specification
75h = 'ENDP without PROC'
Found ENDP without a valid PROC. NBASM Probably found error with PROC
line.
76h = 'Diagnostic: Could use JMPS or JMP SHORT'
Simply change a long jump to a short jump by adding the short keyword.
(jmp short there)
77h = 'NEAR or FAR expected'
Need a type specifier with the PROC keyword
78h = 'Data too long'
Most likely you are putting an immed16 into a DB
79h = 'Illegal size for stack'
Stack size can only be 64 bytes to 65534 bytes long.
7Ah = 'Not allowed in COM file'
You have used a function that can not be used in a .COM file.
- Can not use .DATA
- Other items specified in this documentation
7Bh = 'Symbol not found in Lib File'
You have tried to call an external proc not found in the specified
library.
7Ch = 'Need .MODEL [type]'
Specify .tiny or .small
7Dh = 'Symbol needs 186'
7Eh = 'Symbol needs 286'
7Fh = 'Symbol needs 286P'
80h = 'Symbol needs 386'
81h = 'Symbol needs 386P'
82h = 'Symbol needs 486'
83h = 'Symbol needs 586+ (Pentium/Pro/II/III)'
84h = 'Symbol needs .87'
85h = 'Symbol needs .187'
86h = 'Symbol needs .287'
87h = 'Symbol needs .387'
88h not specified
89h = 'Only read first 65535 bytes of include file'
Include files can be only 65535 bytes in size
8Ah = 'Can not use ret as 'exit code' in .OBJ'
You must use .exit or define your own exit code
8Bh = 'Can not use ret if '.start' used'
The .start system macro changes the Stack segment.
Therefore you can not use the PSP:[00] ret trick.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 46
8Ch = 'Error with Lib File'
The wanted library file is either corrupt or not a valid NBASM lib file.
8Dh-FEh not specified
FFh = 'Unknown error'
Since NBASM now requires a DPMI (DOS Protected Mode Interface), you may
receive the following error if you are running NBASM from TRUE DOS:
"Load error: no DPMI - Get csdpmi*b.zip"
This simply is asking for 'cwsdpmi.exe' which is in the archived file:
csdpmi*b.zip
from:
ftp://ftp.bu.edu/pub/mirrors/simtelnet/gnu/djgpp/v2misc/csdpmi5b.zip
or
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2misc/csdpmi5b.zip
(more links available upon request)
Once unzipped, the only file you need to run NBASM is CWSDPMI.EXE.
It is a 20k file and will be loaded before NBASM runs, and then
unloaded after NBASM runs. If this is to slow for you, you can
install cwsdpmi as a TSR and it will remain resident.
Place cwsdpmi in a directory that is pointed to by PATH or in the
same directory that NBASM resides.
NBASM requires no other external files.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 47
Precautions:
Please note that all code that is used/called from a library with the
.external procname technique is added to the end of your .com file. So if
you plan to use the remaining memory after your .com file, please take in
mind the size of the code included by the library, or you might overwrite
the code and crash the machine.
I plan to add some code and documentation to NBASM to allow the coder to
find where the end of this added code will be. Until then, be careful
about assuming where the code is and how long it is.
I have added most of the 32 bit instructions and registers. However, I
have not fully tested them yet, so please use caution when using the 32
bit instructions. I will fully test them soon.
I have not added all of the FPU instructions yet, and some of the ones
that are included, may not work as expected. Sorry.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 48
Examples
(See the included DEMO1.ASM file for another example)
-- Example #1: ------------------------------------------------------
; this example shows the use of the '@LABEL' directive.
.model tiny
.code
mov ah,09 ; print string
mov dx,offset @label ; use 'unique' name
int 21h
mov ah,09 ; print string once more
mov dx,offset @label ; use same 'unique' name
int 21h
jmp short SkipData
@label db 'Both of the @label above points to this place (1)',36
SkipData mov ah,09 ; print string again
mov dx,offset @label ; use same 'unique' name
int 21h
int 20h ; exit
@label db 'The above @label points to this place (2)',36
.end
-- Example #2: ------------------------------------------------------
.model tiny ; create COM file
.186 ; allow 186 instructions
.external prthex, prtstring ; include the code for prthex and prtstring
.code ; start of code segment
push offset msg1 ; use library function (prtstring)
call prtstring ;
mov ax,offset msg2 ; use library function (prtstring)
push ax ;
call prtstring ;
push 1234h ; put 1234h on the stack
call prthex ; and print it as hex
mov dl,'h' ; print the trailing 'h'
mov ah,02 ;
int 21h ;
int 20h ; exit to DOS
msg1 db 13,10,'This is an example of the .external directive',0
msg2 db 13,10,"For this example we use the 'prtstring' "
db "and 'prthex' routines"
db 13,10,'We will print the value 1234h here: ',0
.end
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 49
Appendix A - Undocumented instructions supported by NBASM
** SALC **
Instruction: SALC (accepts no arguments)
Name: "Set AL to Carry"
opcode: D6h
Min Processor: .8086
Max Processor: none
Flags modified: none
This instruction sets AL to 0FFh if the Carry Flag is set (CF=1), or
clears AL (00h) if the Carry Flag is clear (CF=0).
** POP CS **
Instruction: POP CS
Name: "POP CS"
opcode: 0Fh
Min Processor: .8086
Max Processor: .286
Flags modified: none
Moves the current word from the stack into CS.
********** Only works on the 8088/8086 thorough the 80286.
From the 80386, Intel used this opcode as an extension opcode.
** UMOV **
Instruction: UMOV
Name: "User MOVe"
opcode: 10h-13h
Min Processor: .386
Max Processor: .486
Flags modified: none
This instruction is identical to the following instructions:
MOV memreg,reg
MOV reg,regmem
The only difference is that when the CPU is in the state which it has the
hidden memory active, the user can now transfer data to and from the user
memory while the hidden memory is active.
I have not tested this instruction, so use CAUTION when using this
instruction. Make sure that NBASM assembled it correctly before you use
it. If you have tested this instruction, please let me know what you
find. Thank you
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 50
Appendix B - Misc notes on some instructions supported by NBASM
LOOPx and JCXZ - use CX or ECX
NBASM does not place a size op (67h) in front of LOOPx in
either RMODE *or* PMODE. The current default size is assumed.
e.g.: If you are in rmode and want to use ECX as the
counter, place a 67h byte before the loop line using
a DB line or .adsize (example below).
If you are in pmode and want to use CX as the counter,
place a 67h byte before the loop line using a DB line.
(.adsize and 'db 67h' assemble identically)
.rmode
db 67h ; use ECX as the counter
loop there
.adsize ; use ECX as the counter
jcxz there
.pmode
db 67h ; use CX as the counter
loop there
.adsize ; use CX as the counter
jcxz there
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 51
Structures and Struct
NBASM allows C like structure use. You give the struct a name and use
the STRUCT declaration keyword. Then you must declare each member with
an appropriate size of: byte, word, dword, fword, qword, or dup.
Example:
STRUCT_NAME struct
member1 byte ; member1 is of byte size
member2 word ; member2 is of word size
member3 dword ; member3 is of dword size
member4 fword ; member4 is of fword size (6 bytes)
member5 qword ; member5 is of qword size (8 bytes)
member6 dup 10 ; member6 is 10 bytes in length.
STRUCT_NAME ends ; end of structure declaration.
A Note: You don't have to place the stuct name on the ENDS line,
but if you don't, make sure that ENDS does not start in column one.
NBASM places this structure in a Structure Table. However, your code
does not have access to it yet. You must define a symbol with the
type of this structure using the ST directive. Example:
OurStruct st STRUCT_NAME
Now you can access the structure and its members.
mov ax,OurStruct.member2
mov eax,OurStruct.member3
Please note, as with C, you can define as many symbols with this type
as you have room. However, you must define the structure type before
you use the ST directive to declare the symbol.
OurStruct st STRUCT_NAME
NewStruct st STRUCT_NAME
AStruct st STRUCT_NAME
All three above are valid symbols, are of type STRUCT_NAME, and occupy
three different memory blocks.
You can also initialize data to the structure when you use the ST
directive. Look at the following line:
OurStruct st STRUCT_NAME uses 12h,1234h,12345678h,12345678h,12345678h,"ab"
The above line would create the symbol OurStruct of type STRUCT_NAME and
initialize each of its members to the values that follow the USES
directive respectively.
To use more than one line to initialize the data, simply use a backslash
on the end of the line:
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 52
OurStruct st STRUCT_NAME uses 1, \ ; first member = 1
2, \ ; second member = 2
...
3 ; last member = 3
***** Please note: If you want to initialize one of the members,
you must initalize all members before that member.
You do not have to initialize all members after the last desired
initialization.
***** Please note: Currently you can not nest Structures.
A note about using the 'DUP immed' declaration. You place a value
after the DUP directive to tell NBASM what size to create this member.
If you want to declare a string to this member, you must declare the
size large enough to hold the proceeding NULL byte (if any).
If you declare a member as:
member6 dup 10 uses "0123456789"
The string will not be null terminated.
However, if you do the following:
member6 dup 11 uses "0123456789"
NBASM will null terminate the string for you. If the size of the member
plus the NULL terminator is larger than the declaration size, the rest
of the data in the member's space is undefined and may be random values.
For example:
member6 dup 10 uses "01"
Will declare a member with the following string value:
30h 31h 00h ??h ??h ??h ??h ??h ??h ??h
You may use the SIZEOF directive to get the size of a structure by using
the following:
mov ax,sizeof(STRUCT_NAME)
Notice that you MUST use the TYPE define rather than the actual symbol
you declare with the ST directive. To see more on SIZEOF, go to
page 54.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 54
NBASM also allows UNIONs with in your STRUCT defines. A UNION
is where multiple variables get the same offset from the start
of the STRUCT. This is useful for numerous programming techniques.
Example:
; a demo struct, allowing the second members' actual memory to be
; accessed via two different symbol names.
A_STRUCT_1 STRUCT
a_char byte
UNION
a_short1 word
a_short2 word
ENDU
a_long dword
A_STRUCT_1 ENDS
The above structure occupies 7 bytes. Now declare a symbol as
usual.
a_symbol ST A_STRUCT
a_symbol.a_char is at offset 0 in the structure
a_symbol.a_short1 is at offset 1 in the structure
a_symbol.a_short2 is *also* at offset 1 in the structure
a_symbol.a_long is at offset 3 in the structure
UNION's are used in many types of programming. However, if
you don't know how to use a UNION member, it may be difficult
to do so.
** Currently, UNIONs can only reside in a STRUCT declaration...
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 54
NBASM allows the C like SIZEOF directive. The following datatypes
are currently available for use with the SIZEOF directive.
1. byte, word, dword, fword, qword
2. STRUCT declarations
**** I hope to expand to more types soon *****
Example of the types listed in number 1 above:
mov ax,sizeof(byte) ; returns ax = 1
mov ax,sizeof(word) ; returns ax = 2
mov ax,sizeof(dword) ; returns ax = 4
mov ax,sizeof(fword) ; returns ax = 6
mov ax,sizeof(qword) ; returns ax = 8
Example of the type listed in number 2 above:
newstruct struct
member1 byte
member2 dup 10
member3 dword
ends
mov ax,sizeof(newstruct) ; returns ax = 15
I hope to add more functionality to it soon.
A few things I plan to add: size of actual symbols,
string lengths, immediates, etc.
See the next page about POINTER use with structures and their
member offsets.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 54
NBASM now allows you the use pointers to member in a structure
defination for use with registers.
For example, if you have more than one defined structure of the
same structure type...
NEWSTRUCT struct
member1 byte
member2 dup 10
member3 dword
NEWSTRUCT ends
First st NEWSTRUCT
Second st NEWSTRUCT
Third st NEWSTRUCT
...and want to use a register instead of the structname.membername
technique, with out pointers you would have to do something like:
mov di,offset First
mov cx,3
loopit:
mov byte [di+0],12h ; put 12h into member1
mov dword [di+11],12345678h ; put 12345678h into member3
add edi,sizeof(NEWSTRUCT)
loop loopit
However, what happens when you add or modify the structure
definition? You would have to go and calculate each instance
all over again. Not fun, right :)
So let us use pointers:
mov di,offset First
mov cx,3
loopit:
mov byte [di+NEWSTRUCT->member1],12h ; put 12h into member1
mov dword [di+NEWSTRUCT->member3],12345678h ; write to member3
add edi,sizeof(NEWSTRUCT)
loop loopit
This way, when you add or delete members from the structure, you
don't have to go and change each instance.
Please note that NEWSTRUCT->member1, though similar to C's pointers,
is NOT the same as C's pointers.
'NEWSTRUCT->member1' simply returns the offset from the base of
NEWSTRUCT which in this case is 0.
'NEWSTRUCT->member3' simply returns the offset from the base of
NEWSTRUCT which in this case is 11.
With this in mind, you can use pointers in other areas too:
mov ax,NEWSTRUCT->member3
will get the offset of member3 in the NEWSTRUCT structure.
Please note that you must use the name of the stucture used on
the structure definition line (struct line). You can not use
the name of the actual allocated structure from the ST line.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 55
Please note that the STRUCT defination of the structure must have
already been defined before you use the pointer operand.
There is no worry about the pointer operand adding extra code to
your executable if it returns a zero in a memory operand.
For example:
mov ax,[di+STRUCT->firstmember]
will produce,
mov ax,[di]
will not produce,
mov ax,[di+0]
if firstmember is the first member of the structure. i.e.:
'firstmember' is at offset zero from the top of STRUCT.
This POINTER addition to NBASM32 is a new addition and has not
been completely tested yet. If you find an error, please let
me know about it.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 56
NBASM now has the .ENUM operator. This operator will set a list
of equates to consecutive order, or enumerate them...
.ENUM ZERO, ONE, TWO, THREE, FOUR, FIVE
.ENUM SIX, SEVEN, EIGHT, GUESS ; <- read below. SIX != 6
The above two lines will create 10 EQU symbols with the first symbol
equal to 0, the second to 1, etc., with the last one to 3. Yes, 3.
Each time you use the .ENUM operator, the count is reset to zero.
You can place ENUM's anywhere in your code. However, you must use
an .ENUM before the specified symbol is used in your code.
You may have more than one line for each .ENUM using the '\' operator.
.ENUM ZERO, \ ; a value of zero
ONE, \ ; a value of one
TWO, \ ; a value of two
ETC ; a value of three (and end of line)
However, currently with NBASM's parser, you can only have 126 symbols
per .ENUM.
** Do not have more than 126 symbols per .ENUM operator **
The .ENUM operator should be identical to the EQU operator, except
for the multiple declarations and consecutive numbering.
i.e.: You should use .ENUM symbols just like EQU symbols.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 57
NBASM now has the beginnings of the MS .OBJ compatible file output
for use in linking other routines written by other languages. Please
note that it is just being developed and may not work correctly in all
situations.
Here are the current capabilities:
- You can create an .OBJ file with 64k of memory for all three
segments: .code, .data, and .stack
- NBASM will create a valid (I hope) .OBJ file ready for linking
with any MS compatible 16-bit segmented linker to create an
.EXE ready for execution on a MS DOS compatible 16-bit operating
system. (see below for a free linker)
Here are the items that do not work yet, but are planned to be
implimented soon. Use at your own risk if you use these items
in your code. (i.e.: These are known not to work yet.)
- Do not link any other .OBJ files with the NBASM created one.
Currently, NBASM does not impliment external or multiple
functions/labels/offsets/etc.
If you want multiple files used in your .OBJ format, simply
included the source with the include directive.
- No library's are included or supported (yet).
- Only 16-bit DOS .OBJ's are supported (for now).
You may use the .code and .data directives more than once in
your source file(s). This will make it easier to see your
data that corresponds to the code, or visa-versa.
Example:
.model small
.stack 100h
.data
label1 db 13,10,'This gets printed by the code below',0
.code
mov si,offset label1
.
. prtstring code here
.
; the very next instruction to be executed is the
; 'mov ax,1234h' below. *NOT* the data that is next.
.data
label2 db 13,10,'No need for a 'jmp around' in the .code'
db 13,10,' above, since NBASM will "combine" all segments',0
.code
mov ax,1234h
; this is the very next instruction to be executed after
; the last instruction in the .code part above.
; No need to 'jump over the data' above.
.exit
.end
NBASM places all .data and .code segments in the .OBJ file.
Then the linker combines them and places them in the .EXE
file in the order given: .DOSSEG (default) or .ALPHA
(.DOSSEG is default, and .ALPHA is not yet supported)
Please use the .OBJ format for testing purpose only. If you test
a program you have written with this format, and it seems to
work well, continue using it. However, please note that
the .OBJ functionability will change (hopefully for the better)
through out its build. If you find any errors, please let me
know with as much detail as you can.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 58
Note on the SHR/SHL and SHRD/SHLD instructions.
(I use SHRD in this note, but the same goes for SHLD)
Since the
shr dword [ebx],cl
instruction can also be
shrd [ebx],cl
this makes it confusing when the shrd (double precision)
instruction is used.
Since the shrd (double precision) instruction uses three
operands, and the 'shr dword' instruction only uses two
operands, NBASM correctly output code for each.
For your sake, I would suggest using
shr dword [ebx],cl
instead of
shrd [ebx],cl
and the for the double precision shrd instruction, use
shrd [ebx],eax,cl
This should keep the confusion to a minimum.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 59
Most any brand of 16-bit segmented linker will work on NBASM
.obj files.
***However***, while I do a lot more testing and work on this
part of NBASM, please use the associated linker NBL only.
You may obtain NBL from:
http://www.cybertrails.com/~fys/newbasic.htm
or a direct link to the .ZIP file:
http://www.cybertrails.com/~fys/zips/nbl.zip
Thank you for your support.
-=-=-=- NewBasic Assembler -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Page 60
INDEX...
Coming soon to a theater near you :)