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:

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

 

Категории