A name in a module is private to it until the module declares it PUBLIC; then the object file carries it for the linker. A module that uses a name defined elsewhere declares it EXTRN with its type, so the assembler knows how to encode each use: NEAR and FAR for procedures (a near or far CALL), BYTE, WORD and DWORD for variables, ABS for a constant. The assembler leaves the address blank and the linker fills it in.
; MAIN.ASM: the program; PRINT comes from another module.MODEL SMALL.STACK 256.DATAMSG DB 'Two modules, one program', 13, 10, '$'.CODEEXTRN PRINT:NEARSTART: MOV AX, @DATAMOV DS, AXMOV DX, OFFSET MSGCALL PRINTMOV AX, 4C00hINT 21hEND START
; PRINT.ASM: a module of routines for others to call.MODEL SMALL.CODEPUBLIC PRINT; PRINT: write the $-terminated string at DS:DXPRINT PROC NEARMOV AH, 09hINT 21hRETPRINT ENDPEND
Both modules use the small model, so their .CODE sections are the same segment (_TEXT) and their .DATA sections the same _DATA: the linker puts the pieces of a segment next to each other, and a near CALL from MAIN reaches PRINT. Only one module ends with END start-label; that label is the program's entry point. Only one needs .STACK.
Assemble each, link once
ML /c MAIN.ASM PRINT.ASM ; MASM: two .OBJ filesLINK MAIN+PRINT,PROG,PROG.MAP ; ; objects, program, mapML /FePROG.EXE MAIN.ASM PRINT.ASM ; MASM: the same in one commandJWASMR MAIN.ASM PRINT.ASM ; JWasm: two .OBJ filesJWLINK format dos file MAIN.OBJ,PRINT.OBJ name PROG.EXE option map
When one module changes, only it is assembled again before the link. That is the point of modules in a big program, and what NMAKE (MASM) and MAKE (Borland) automate.
Libraries
A library (.LIB) is a file of object modules with an index of their public names. The linker searches it only for names still missing after the object files, and takes just the modules that define them, so a library of a hundred routines adds only the ones the program calls.
LIB UTIL.LIB +PRINT.OBJ ; ; MASM: create UTIL.LIB, add PRINTLINK MAIN,PROG,,UTIL.LIB ; ; libraries are the fourth fieldJWLIB -n UTIL.LIB +PRINT.OBJ ; JWlib: -n makes a new libraryJWLINK format dos file MAIN.OBJ library UTIL.LIB name PROG.EXETLIB UTIL +PRINT ; BorlandTLINK MAIN, PROG,, UTIL
Pitfalls
A name declared EXTRN that no module makes PUBLIC stops the link: LINK reports error L2029 "unresolved external", TLINK "Undefined symbol", JWlink "undefined reference". The type in EXTRN must match the definition: a near CALL to a FAR procedure, which ends in a far return, does not come back where it should. A .EXE without a stack segment gets LINK's warning L4021 "no stack segment" and runs on whatever stack DOS left it.