home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hall of Fame
/
HallofFameCDROM.cdr
/
prog4
/
assm.lzh
/
ASMTUTR2.DOC
< prev
next >
Wrap
Text File
|
1983-12-11
|
25KB
|
407 lines
so. An exception is the saving and restoring of registers at
entrance to and exit from a subroutine; here, if the subroutine is
long, you should probably PUSH everything which the caller may need
saved, whether you will use the register or not, and POP it in
reverse order at the end.
Be aware that CALL and INT push return address information on the
stack and RET and IRET pop it off. It is a good idea to become
familiar with the structure of the stack.
c. In practice, to invoke system services you will use the INT
instruction. It is quite possible to use this instruction effec-
tively in a cookbook fashion without knowing precisely how it
works.
d. The transfer of control instructions (CALL, RET, JMP) deserve care-
ful study to avoid confusion. You will learn that these can be
classified as follows:
1) all three have the capability of being either NEAR (CS register
unchanged) or FAR (CS register changed)
2) JMPs and CALLs can be DIRECT (target is assembled into instruc-
tion) or INDIRECT (target fetched from memory or register)
3) if NEAR and DIRECT, a JMP can be SHORT (less than 128 bytes
away) or LONG
In general, the third issue is not worth worrying about. On a for-
ward jump which is clearly VERY short, you can tell the assembler
it is short and save one byte of code:
JMP SHORT CLOSEBY
On a backward jump, the assembler can figure it out for you. On a
forward jump of dubious length, let the assembler default to a LONG
form; at worst you waste one byte.
Also leave the assembler to worry about how the target address is
to be represented, in absolute form or relative form.
e. The conditional jump set is rather confusing when studied apart
from the assembler, but you do need to get a feeling for it. The
interactions of the sign, carry, and overflow flags can get your
mind stuttering pretty fast if you worry about it too much. What
is boils down to, though, is
JZ means what it says
JNZ means what it says
JG reater this means "if the SIGNED difference is positive"
JA bove this means "if the UNSIGNED difference is positive"
JL ess this means "if the SIGNED difference is negative"
JB elow this means "if the UNSIGNED difference is negative"
JC arry assembles the same as JB; it's an aesthetic choice
IBM PC Assembly Language Tutorial 10
You should understand that all conditional jumps are inherently
DIRECT, NEAR, and "short"; the "short" part means that they can't
go more than 128 bytes in either direction. Again, this is some-
thing you could easily imagine to be more of a problem than it is.
I follow this simple approach:
1) When taking an abnormal exit from a block of code, I always use
an unconditional jump. Who knows how far you are going to end
up jumping by the time the program is finished. For example, I
wouldn't code this:
TEST AL,IDIBIT ;Is the idiot bit on?
JNZ OYVEY ;Yes. Go to general cleanup
Rather, I would probably code this:
TEST AL,IDIBIT ;Is the idiot bit on?
JZ NOIDIOCY ;No. I am saved.
JMP OYVEY ;Yes. What can we say...
NOIDIOCY:
The latter, of course, is a jump around a jump. Some would say
it is evil, but I submit it is hard to avoid in this language.
2) Otherwise, within a block of code, I use conditional jumps
freely. If the block eventually grows so long that the assem-
bler starts complaining that my conditional jumps are too long
I
a) consider reorganizing the block but
b) also consider changing some conditional jumps to their
opposite and use the "jump around a jump" approach as shown
above.
Enough about specific instructions!
6. Finally, in order to use the assembler effectively, you need to know
the default rules for which segment registers are used to complete
addresses in which situations.
a. CS is used to complete an address which is the target of a NEAR
DIRECT jump. On an NEAR INDIRECT jump, DS is used to fetch the
address from memory but then CS is used to complete the address
thus fetched. On FAR jumps, of course, CS is itself altered. The
instruction counter is always implicitly pointing in the code seg-
ment.
b. SS is used to complete an address if BP is used in its formation.
Otherwise, DS is always used to complete a data address.
c. On the string instructions, the target is always formed from ES and
DI. The source is normally formed from DS and SI. If there is a
segment prefix, it overrides the source not the target.
IBM PC Assembly Language Tutorial 11
Learning about DOS
__________________
Learning about DOS
Learning about DOS
Learning about DOS
I think the best way to learn about DOS internals is to read the technical
appendices in the manual. These are not as complete as we might wish, but
they really aren't bad; I certainly have learned a lot from them. What you
don't learn from them you might eventually learn via judicious disassembly
of parts of DOS, but that shouldn't really be necessary.
From reading the technical appendices, you learn that interrupts 20H
through 27H are used to communicate with DOS. Mostly, you will use inter-
rupt 21H, the DOS function manager.
The function manager implements a great many services. You request the
individual services by means of a function code in the AH register. For
example, by putting a nine in the AH register and issuing interrupt 21H you
tell DOS to print a message on the console screen.
Usually, but by no means always, the DX register is used to pass data for
the service being requested. For example, on the print message service
just mentioned, you would put the 16 bit address of the message in the DX
register. The DS register is also implicitly part of this argument, in
keeping with the universal segmentation rules.
In understanding DOS functions, it is useful to understand some history and
also some of the philosophy of MS-DOS with regard to portability. General-
ly, you will find, once you read the technical information on DOS and also
the IBM technical reference, you will know more than one way to do almost
anything. Which is best? For example, to do asynch adapter I/O, you can
use the DOS calls (pretty incomplete), you can use BIOS, or you can go
directly to the hardware. The same thing is true for most of the other
primitive I/O (keyboard or screen) although DOS is more likely to give you
added value in these areas. When it comes to file I/O, DOS itself offers
more than one interface. For example, there are four calls which read data
from a file.
The way to decide rationally among these alternatives is by understanding
the tradeoffs of functionality versus portability. Three kinds of porta-
bility need to be considered: machine portability, operating system porta-
bility (for example, the ability to assemble and run code under CP/M 86)
and DOS version portability (the ability for a program to run under older
versions of DOS>.
Most of the functions originally offered in DOS 1.0 were direct descendents
of CP/M functions; there is even a compatibility interface so that programs
which have been translated instruction for instruction from 8080 assembler
to 8086 assembler might have a reasonable chance of running if they use
only the core CP/M function set. Among the most generally useful in this
original compatibility set are
IBM PC Assembly Language Tutorial 12
09 -- print a full message on the screen
0A -- get a console input line with full DOS editing
0F -- open a file
10 -- close a file (really needed only when writing)
11 -- find first file matching a pattern
12 -- find next file matching a pattern
13 -- erase a file
16 -- create a file
17 -- rename a file
1A -- set disk transfer address
The next set provide no function above what you can get with BIOS calls or
more specialized DOS calls. However, they are preferabƒâ ƒ9$ ƒαß ƒ ƒƒƒ üα߃ƒÅŃƒƒÇǃƒ