home *** CD-ROM | disk | FTP | other *** search
- Basm Tasm Mangle and Spaghetti It
-
-
-
-
-
-
- (A brief and simplified explanation of assembler interfacing to Turbo C++.)
-
- (This article is intended for "REAL" DOS programmers:
- those who don't eat quiche or drive little plastic cars.)
-
-
-
-
-
-
-
-
- by: Victor E. Cummings
-
-
-
-
-
-
-
-
-
-
-
-
-
- Trademarks contained herein are attributed to their respective owners.
-
- Introduction:
-
- This is a frequently asked question: just when and where should
- I use assembler interfaces in my C programs? With the introduction
- of Turbo Assembler and Turbo C++, this question becomes even more
- difficult. The facilities that Tasm offers and the inclusion of
- Basm the internal inline assembler make the interface so versatile
- and easy that the question is not how but why and where and what
- method of many do I use?
-
- This article is for the programmer who wishes to add assembler
- interfaces to C programs. With the introduction of MASM 6.0 it is
- increasingly possible to do the reverse with ease. MASM 6.0 got
- a marginal review from PC Magazine, but I'm not sure that I agree.
- It offers loop constructs similar to a higher level language which
- work gracefully, and they have many good examples included with the
- assembler that you can modify for your own use. Tasm 2.5 just does
- not offer that. The idea of creating assembler programs with a few
- C interface routines is beyond the scope of this article, though
- calling C routines from assembler is discussed. If you would like
- to add higher level constructs to Tasm so you have that facility,
- The MS-DOS Developer's Guide by the Waite Group offers a tool kit
- which does just that, and may indeed have been where Microsoft got
- the idea.
-
- If you are an assembler programmer using C interface routines, it
- is doubtful that you have downloaded this article in the first
- place, because the scope is too small for you.
-
- Wherever possible this article is written at the 7th grade level
- so that you may quickly get the information you need without long
- winded sentences.
-
- The GAZINTAS and the GAZOWTAS:
- Definitions:
-
- GAZINTA: What GAZINTA here >────┐
- │
- Also mathematical term ┌─────┼──────┐
- meaning quotient. │ │ │ ┌────┐
- [origin obscure] │ └>─────>──>─┤ │
- └────────────┘ ^ └────┘
- │
- GAZOWTA: What GAZOWTA there ──────────────┘
-
- Where ever possible, the GAZINTA and GAZOWTA method of definitions
- will be used in the following explanations. This context is used
- to add some humor to a dry subject, but not to insult your intel-
- ligence. The discussion does not get into a lot of detail, but
- attempts to help the reader gain the basic concepts quickly.
-
-
-
-
- When to use Basm:
-
- Basm is the assembler which is internal to the new Turbo C++
- compiler. It has obvious limitations which are documented in the
- manual. Where is Basm. Basm works silently. No message is given
- by the compiler unless Basm is unsuccessful in compiling your
- inline statements. Simply stated: if you have existing statements
- which include the #pragma inline directives then remove them. I
- have provided an example by Al Stevens which I have converted to
- Borland C++ 2.0 code. In the example, the #pragma inline statement
- has been removed. Compile the example "IBMPC.CPP" by using the
- command line: bcc -c ibmpc. Then remove the comment preceding
- #pragma inline, and the compiler will produce an assembler version
- of the file and call Tasm to assemble it. The Basm compiler works
- more efficiently to produce the code without having to produce
- assembler output and then assembling it. The result is a faster
- compile with identical output.
-
- Inline assembly is really used at its best as in this example. It
- should be used when only a few assembler statements are needed and
- where time is of the essence as in waiting to write a character
- after a video retrace.
-
- Inline assembly is useful for this purpose. Inline assembly allows
- more than it really should. You can even use it to call a C
- function. In a word: don't. If you need to do something that
- complicated, you should consider making an assembler call. It is
- really easy to do with Turbo Assembler 2.5 so why not? The most
- you will want to do is pass a few variables to the inline code and
- let it work fast and return.
-
- When would I want to use Tasm with the #pragma inline directive?
-
- Don't use it where Basm will work. If you can remove it, then do.
- Your code will compile more quickly. If you wish to see the result
- of your assembly for debugging purposes then use the -S command
- line option supplied with the compiler to get an assembly output
- for your file and stop the assembly process. The IBMPC.CPP file
- is a good file to try this with, because it does not include many
- of the library routines, and it will give you a simple example to
- study to discover how inlines are handled by the compiler. The
- resulting IBMPC.ASM file has been included in this archive.
-
- What is a mangled name?
-
- Examine the resulting file produced with the -S compiler directive:
- IBMPC.ASM. The name is descriptive. If you look at the resulting
- label names created by the compiler, you will see that the compiler
- has mangled the heck out of them as the name implies. The way that
- the compiler mangles the names is not well documented in the
- compiler documentation. The compiler tells you to create the
- assembly output in this manner to study the output. They include
- this as a training measure for the mangled names without having to
- add to the mass of their manuals which are already quite bulky.
- If you need to write assembler interfaces which will be used in
- object oriented programming style, then you may produce the
- function header for the function first in your C++ code. Then
- compile the file using the -S compiler directive. This will give
- you the mangled name to use in your assembly code commented above
- by the header that your created. Then to speed this up you can
- just insert your code into the code that was started for you by the
- compiler. Let the compiler do the work for you. I have provided
- an example called FICTION.CPP which contains some headers for some
- fictional functions. When you are designing your application, and
- you decide that assembly interfacing would be the way to go for
- several of your functions, then you may use this technique. I
- compiled the FICTION.CPP file to get the FICTION.ASM file contained
- in this archive.
-
- When I looked at the assembler output that I saw, it really made
- me as a REAL DOS programmer mad. Someone at Borland really decided
- to mangle the heck out of my public names! Well if the compiler
- wants mangled names, I might as well let it mangle them for me.
- One thing that I was really happy about: my fingers get tired
- every time I have to type push bp, and the compiler already started
- the code which I can snip. Really clean no? Do these guys at
- Borland ever take a lunch break? The compiler even commented the
- assembly code and added only the bare essentials which I would have
- needed to type anyway. It even inserted my local variable names
- in as comments. If the guys at Borland had taken one less lunch
- break, I would have taken me two less milliseconds to set up my
- local stack for the assembler call. The compiler already
- calculated the ret instruction for the pascal call and even will
- insert the references to the base pointer if you initialize your
- variables. Then all you have to do is make the references to the
- base pointer (bp) into EQU statements which you can then reference
- by name. What could be easier.
-
- Design Philosophy:
-
- When designing an application, and you just know that you are going
- to need an assembler call, then just code the header for the
- fictional function, initialize all the variables and compile with
- the -S compiler option and snip the stub for your function. An
- example that was created in about 40 seconds from the assembler
- output is contained in this archive and is called SNIP.ASM. I
- added only a few changes to make a very optimal stub for my
- fictional routine.
-
- The hard part:
-
- The hard part is where do you use assembler interfacing and where
- do you not. If your program is working fairly nicely and at a
- speed you are happy with then leave it in C. But you get into the
- coding and you find that there is one spot which is just too
- SLOOOOOOOOOOOOOOOOOOOOOOOOOOOOOW then you should resort to
- assembler. In my next article for Real DOS programmers entitled
- "Its Got To Be Assembler Here-->" I'll furnish you with a working
- example of where assembler can not be avoided with the equivalent
- C++ code that you can use in your programs.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-