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 :)