home *** CD-ROM | disk | FTP | other *** search
-
-
-
- 1
-
- USING A86
-
-
- This is intended as a guide to get A86 to work for all the
- programs in the Tutor. It only covers things that won't work or
- things A86 does differently. It does not cover any of the
- benign options like local labels.
-
-
- ===== CHAPTER 1
-
- You need to take your text editor and change the last line of the
- template files. At the moment they read:
-
- END start
-
- You may either eliminate the line or change it to:
-
- END main
-
- If you don't, you will get this error message:
-
- END start~40 Conflicting Multiple Definition Not Allowed~
-
- Do this for all the original template files, because this line
- will always cause an error. You will find out why when you get to
- Chapter 10.
-
- You should also insert the word PUBLIC just before the line with
- ASSUME. Do this in all the template files.
-
- PUBLIC
- ASSUME cs:CODESTUFF, ds:DATASTUFF
-
- You will find out why in Chapter 15.
-
-
- A86 has some unusual defaults, so you need to change them when
- you assemble a file. If your file is named myprog.asm, the
- command line you want to use for the rest of this tutorial is:
-
- >a86 +DOSX myprog.asm
-
- You must use the file extension .asm when you call the program.
- You can make a batch file (let's call it QASM.BAT) which has:
-
- a86 +DOSX %1.asm
-
- Then all you need to do is:
-
- >qasm myprog
-
- Those four options on the command line are:
-
-
- ______________________
-
- The PC Assembler Tutor - Copyright (C) 1990 Chuck Nelson
-
-
-
-
- The PC Assembler Tutor 2
- ______________________
-
- +D numbers with leading 0s are default decimal
- +O make an object file
- +S don't create an ancillary symbol table
- +X require specific declaration of external information
-
- They should be used from now on. When you are through with all
- the chapters, you can decide whether you want to continue using
- them all. If you are using D86, you need to eliminate the 'S'.
- The declaration should be +DOX since you will need the symbol
- table.
-
-
- ===== CHAPTER 2
-
- Please read all of chapter 2 before you read these comments.
-
-
- The defaults and definitions are the same with two exceptions.
- First, any number that begins with a '0' is hex by default. That
- is, 22 is a decimal number and 022 is a hex number. This has some
- serious side effects. Take the number:
-
- 0847d
-
- This is 847, right? No. It is 0847Dh = 34,637. In Chapter 7 we
- will use these binary numbers:
-
- 01001011b
- 00000100b
-
- These should be 75 and 4 respectively, but A86 evaluates them as
- 01001011Bh = 268500992 and 0100Bh = 4107. Since half of the
- binary numbers you use will start with a 0, half of your binary
- numbers will be wildly incorrect. In order to correct the
- situation, you need to put a +D on the command line. This is the
- 'D' of +DOSX. The D will insure that all numbers starting with 0
- will be decimal. This gets rid of all the side effects.
- Alternatively, you can put:
-
- RADIX 10
-
- at the top of your files before any of the code or data. This has
- the same effect. Of course, if you really do want hex numbers,
- this can be overridden with a specific 'h' after any number.
-
-
- There is another major problem with data definitions. Let's say
- that you want the following definitions:
-
- weight dw ?
- cost dw 20
- profit dw ?
-
- but you forget to put in some of the initializations in your text
- file (a situation which is not unknown):
-
- weight dw
-
-
-
-
- Using A86 3
- _________
-
- cost dw
- profit dw ?
-
- All other assemblers will generate an error. You must either put
- in an initial value or you must say that you want no initial
- value (by putting in a question mark). Not only does A86 not
- generate an error, it does something strange. If there is neither
- initialization nor a question mark, A86 will calculate an address
- for the variable but WILL ALLOCATE NO SPACE FOR IT. What this
- means is that in our above example, 'weight', 'cost', and
- 'profit' will all be at the same memory address. 'Weight' and
- 'cost' will have the same address with no space allocation.
- 'Profit' will be at the same memory address too, but will have
- space allocated for it.
-
- This is all done silently, so you don't know that this is being
- done. There is no way to shut this off. You might be able to find
- that this is happening by looking at the symbol table, but that
- means that you suspect that it is happening. What you need to
- do whenever you use A86 is:
-
- ALWAYS CHECK ALL DATA TO MAKE SURE THAT IT IS INITIALIZED OR
- HAS A QUESTION MARK
-
-
-
- ===== CHAPTER 10
-
- We now come to some actual differences. A86 does not produce a
- list file. You can read the justification for this in your
- documentation. Does this make a difference? It would be nice to
- have one, but we can normally live without it. Just follow what
- is happening with the MASM listing.
-
- p94 - ASSUME statements. Both TASM and MASM keep track of how you
- want the segments to be referenced. A86 doesn't. It simply
- ignores any ASSUME statements. This means that any segment
- overrides must be coded into the text file with:
-
- mov cx, ss:variable4
- mov cx, es:variable2
- mov cx, ds:variable1
- mov cx, cs:variable3
-
- A86 assumes that all code uses CS (which it must), and that all
- data uses DS unless there is a specific segment override. Is this
- a big imposition? Not really. If you use a segment register other
- than DS, it is normally for dealing with arrays, and in those
- cases you need a segment override anyways. You will find out
- about that in the next chapter.
-
- p97 - END statements. END is not necessary in A86. It knows that
- the end has come when the file is finished. The default starting
- point for an A86 file is the label 'main'. If A86 sees a label
- name after an END statement, then it RENAMES that word 'main',
- and renames all occurances of that word in the file 'main'. It
- does not change the default starting name. This means that if you
-
-
-
-
- The PC Assembler Tutor 4
- ______________________
-
- have a statement like:
-
- END start
-
- and you also have the label 'main' in your file, A86 will change
- all occurances of 'start' to 'main', causing multiple use of the
- same label.
-
-
- ======== Chapter 15
-
- p154 - You do not need PUSHREGS and POPREGS. With A86, PUSH is
- exactly the macro PUSHREGS:
-
- PUSHREGS ax, bx, cx, dx, si
- PUSH ax, bx, cx, dx, si
-
- These are exactly the same. POP shows the actual order that
- things will be popped, while POPREGS has the reverse order so
- that you can use a word processor to copy the PUSHREGS part. For
- the above PUSH declaration, this is the correct POP:
-
- POP si, dx, cx, bx, ax
- POPREGS ax, bx, cx, dx, si
-
- From now on, whenever you see PUSHREGS, change it to PUSH, and
- whenever you see POPREGS, change it to POP but reverse the order
- of registers so that it is the actual order in which things are
- POPped. You can delete the line:
-
- include \pushregs.mac
-
- from your template file.
-
- ; - - - - - - - - - -
-
- Please read the whole chapter before reading the rest of these
- comments.
-
- For some reason, A86 makes ALL normal variables and labels PUBLIC
- unless you specifically tell it not to. The whole thrust of
- programming for the last 20 years (PASCAL, C, and all structured
- languages), has been to make NOTHING public unless specifically
- requested, so this is an unwelcome default setting. You turn it
- off by naming any normal (but not local) variable PUBLIC. In
- fact, if you use the word PUBLIC alone:
-
- PUBLIC
-
- without any name after it, A86 will turn this off. That is why
- you put it in all the template files. Always have this in all
- your assembler files.
-
-
- A86 also assumes that any variable that has no data declaration
- is EXTRN. This is a bad policy. What will happen is the
- following. You are using the variable 'last_occurance' and you
-
-
-
-
- Using A86 5
- _________
-
- misspell it 'last_ocurrance'. A86 sees no data declaration so
- assumes that it is an external variable and assembles the file.
- Three hours later you link the 6 modules of your program together
- and you get a link error. The linker cannot find 'last_ocurrance'
- anywhere.
-
- Just as you should need to explicitly name things PUBLIC, you
- should need to explicitly name things EXTRN. You do this by
- putting +X (forced external declarations) on the command line.
- This is the 'X' in the '+DOSX' that you have been using on the
- command line.
-
-
- ===== CHAPTER 21
-
- You need to change the ORG statement so it is in front of main
-
- ORG 100h
- main proc near
-
- This is because you are using main as the starting address, so it
- must be at 100h. This 100h is optional with A86. If it is making
- a .COM file it automatically starts at 100h. A86 is designed to
- give you a .COM file directly, so all you need to do with a
- single file is:
-
- >a86 +DS myfile.asm
-
- and you will get MYFILE.COM as the output file. In the example
- where we make a .COM file from multiple files, these files are
- set up to be .OBJ files. If you want to make them into a .COM
- file directly, you need to take out all PUBLIC, EXTRN and END
- statements (and adjust PUSHREGS and POPREGS) and then do:
-
- >a86 +DS prog1.asm prog2.asm prog3.asm
-
- making sure that prog1.asm is first. The output file should be
- prog1.com.
-
-
- ===== CHAPTER 26
-
- You need to read all of Chapter 26 before reading any of the
- following.
-
- A86 will work fine with any standard segment definitions. It also
- has two special segment statements of its own. The first:
-
- CODE SEGMENT
-
- will generate the following:
-
- _TEXT SEGMENT PUBLIC 'CODE'
-
- The second statement:
-
- DATA SEGMENT
-
-
-
-
- The PC Assembler Tutor 6
- ______________________
-
-
- is NOT a segment declaration. It generates NO segment, it
- allocates NO space and it initializes NO data. What is it? I'll
- explain how it operates, but I have no idea why it exists.
-
- The first time you use the 'DATA SEGMENT' instruction in a file
- it is followed by ORG:
-
- DATA SEGMENT
- ORG 1000h
-
- ORG relocates the counter for where the assembler is allocating
- space in memory. From this point on, every time you define
- variables:
-
- time dw ?
- distance dw ?
- space dw ?
-
- A86 generates an distinct address for each variable. However, it
- ALLOCATES NO SPACE. This is just an address that the code can use
- when it refers to the variables. If you have the following
- variables:
-
- year dw 1990
- prime dw 73
- cost dw 5167
-
- A86 will generate address for these variables but (1) will
- allocate NO space, (2) will do NOTHING with those initializing
- values and (3) WILL NOT COMPLAIN that you have tried using
- initialized data in a DATA SEGMENT statement. A86 will do the
- equivalent of:
-
- year dw ?
- prime dw ?
- cost dw ?
-
- This data is technically in the CODE SEGMENT. If the code is
- longer than that initial ORG number, some of the code will be in
- the same place as some of the data and if you write to the data
- you will overwrite the code. A86 will not complain.
-
- For instance, we had ORG 1000h (4096d). If the code is 6000 bytes
- long, the last 2000 bytes of code will share the space with the
- data. This leads to either bad data or bad code or both.
-
- Why have this? Well, when DOS loads a .COM file into memory, it
- uses ALL of memory. If I have:
-
- INTSCRN.COM 541 07/23/90 17:45
-
- a .COM file that is 541 bytes long, DOS will allocate about
- 550,000 bytes for it on my computer. 549,459 bytes of this are
- wasted space. It is A86's idea to put data in this wasted space.
- There is no reason for this, so don't do it. If you have a .COM
- file, put all your data in the CODE SEGMENT. If you have an .OBJ
-
-
-
-
- Using A86 7
- _________
-
- file you need to create a legitimate SEGMENT for the DATA. Its
- name cannot be:
-
- DATA SEGMENT PUBLIC 'DATA'
-
- If I have the following program:
-
- ; - - - - - - - - - - - - - - -
- DATA SEGMENT PUBLIC
- data1 db "This is the output string", 13, 10, "$"
- data2 db 100 dup (0)
- ENDS
-
- CODE SEGMENT
-
- main:
- mov ax, seg DATA
- mov ds, ax
-
- mov ah, 09h ; print string
- lea dx, data1
- int 21h
-
- mov ax, 4C00h ; exit
- int 21h
- ; - - - - - - - - - - - - - - -
-
- and I try to make an object file with it, I get the following
- error:
-
- mov ax, seg DATA~61 Overlapping Local Not Allowed~
-
- The ability to put the segment starting address in the segment
- register is a minimal requirement for doing anything. This
- effectively eliminates the possibility of using DATA as the name
- for a segment. Therefore, those of you who use Turbo Pascal need
- to use:
-
- DSEG SEGMENT PUBLIC
-
- as an alternative. This will work with no problems.
-
-