home *** CD-ROM | disk | FTP | other *** search
-
- 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$ ƒαß ƒ ƒƒƒ üα߃ƒÅŃƒƒÇǃƒ