The Assembly Programming Master Book
| ||
| ||
|
Now, consider the INVOKE directive. This is a convenient command. However, for reasons that will be clarified later, I'll use it in my programs only occasionally.
Its convenience is, first, that you don't need to add the @N suffix. Second, this directive takes care of loading the passed parameters into the stack. The following sequence of commands is not used:
PUSH par1 PUSH par2 PUSH par3 PUSH par4 CALL NAME_PROC@N ; N - Number of bytes sent to the stack
Instead, the following is used:
INVOKE NAME - PROC, par4, par3, par2, par1
Here, the role of the parameter can be played by a register, a direct value, or an address. Besides this, for an address it is possible to use both the OFFSET operator and the addr operator.
Modify the PROG1.ASM module (the PROG2.ASM module doesn't need to be modified) as shown in Listing 1.5.
Listing 1.5: Using the INVOKE directive
|
.586P ;Flat memory model .MODEL FLAT, STDCALL ;------------------------------- ; Prototype of the external procedure PROC1 PROTO ; Data segment _DATA SEGMENT _DATA ENDS ; Code segment _TEXT SEGMENT START: INVOKE PROC1 RET ; Exit _TEXT ENDS END START
|
As can be easily seen, the external procedure is now declared using the PROTO directive. This directive allows parameters to be specified when necessary. For example, consider the following line:
PROC1 PROTO :DWORD, :WORD
This means that the procedure needs two parameters having lengths of 4 and 2 bytes, respectively (6 bytes total, indicated as @6).
As I mentioned earlier, I'll rarely use the INVOKE directive. Now, I'll clarify the first reason that I avoid this option: I'm an advocate of the purity of Assembly language. Consequently, any use of macros makes me feel uncomfortable. In my opinion, beginner programmers mustn't let themselves be carried away by macro tools; otherwise , they'll never feel the beauty of this language. As for the second reason, I'll clarify it later.
The scheme presented in Fig. 1.1 shows that it is possible to link both object modules and libraries. If there are several object modules, this will cause some inconvenience. Because of this, object modules are combined into libraries. Using the INCLUDELIB directive is the most convenient and the easiest way to link the library using MASM. The INCLUDELIB directive will be stored in the object code for further use by the LINK.EXE program.
However, how can you create a library from object modules? For this purpose, there is a special program called librarian. Assume that you need to create the LIB1.LIB library consisting of a single module PROG2.OBJ. To achieve this, issue the following command:
LIB /OUT:LIB1.LIB PROG2.OBJ
If it is necessary to add another module to the library (MODUL.OBJ), simply execute the following command:
LIB LIB1.LIB MODUL.OBJ
Here are two more useful examples of using the librarian:
-
LIB/LIST LIB1.LIB Produces the list of library modules
-
LIB/REMOVE:MODUL.OBJ LIB1.LIB Removes the specified module, MODUL.OBJ, from the LIB1.LIB library
Now, return to the example. Instead of the object module, you are now using the LIBI.LIB library. The modified text of the PROG1. ASM program is shown in Listing 1.6.
Listing 1.6: Using the library
|
.586P ; Flat memory model .MODEL FLAT, STDCALL ;------------------------------------------ ; Prototype of the external procedure EXTERN PROC1@0:NEAR ;------------------------------------------ INCLUDELIB LIB1.LIB ;------------------------------------------ ; Data segment _DATA SEGMENT _DATA ENDS ; Code segment _TEXT SEGMENT START: CALL PROC1@O RET ; Exit _TEXT ENDS END START
|
| ||
| ||
|