I cannot connect external files to my program. I am trying to connect a file filled with macros. I have all the files in the same folder. So, HOW DO I PROPERLY EXTERN THESE FILES SO THAT I CAN CALL THE MACROS THAT ARE IN THEM ?
CODE:
include PCMAC.INC
.model small
.stack 100h
.data
Prompt_a DB 'Enter A:$'
Prompt_b DB 'Enter B:$'
Output db 'The sum is $'
CR EQU 0dh ;13 \r moves the cursor to begginig of current row
LF EQU 0ah ;10 new line
.code
EXTERN GETDEC:NEAR, PUTDEC:NEAR
main proc
mov ax, @data
mov ds, ax
_PutStr Prompt_a
call GETDEC ;number in AX after
mov bx, ax
_PutStr Prompt_b
call GETDEC ; still in AX
add bx, ax
_PutStr Output
mov ax, bx
call PUTDEC ;Print num in AX
_PUTCH 13, 10
_exit 0 ; Finished/return to dos
main endp
end main
ERROR MESSAGE:
Assembling file: test.asm
**Error** test.asm(13) Illegal instruction
**Error** test.asm(19) Undefined symbol: GETDEC
**Error** test.asm(22) Undefined symbol: GETDEC
**Error** test.asm(26) Undefined symbol: PUTDEC
Error messages: 4
Warning messages: None
Passes: 1
Remaining memory: 455k
Simply INCLUDE
the file and use the macros.
The EXTRN
directive, note the missing E
†, is used to declare a symbol, like a function, defined in another object file1 that is usually the result of a separate source file (this is typical when mixing C and assembly).
Note
The INCLUDE
directive is like a copy-paste of the content of the included file in place of the directive.
Make sure that the included content is compatible with the "surrounding" - i.e. make sure that copy-pasting the content of the file will generate a correct source.
To use a macro, by its nature of meta-code2, the assembler needs to have access to its code, so INCLUDE
is the right directive3 since it copies the source code of the macro in the current file.
Example
macros.asm
exit MACRO
mov ax, 4c00h
int 21h
ENDM
program.asm
.8086
.MODEL SMALL
.STACK 100h
;Macros are fine here
INCLUDE mc2.asm
_CODE SEGMENT PARA PUBLIC 'CODE' USE16
ASSUME CS:_CODE, DS:_CODE
ORG 100h
__START__:
;This is the macro in the macros.asm file
exit
_CODE ENDS
END __START__
Note that you have to assemble and link program.asm, the other file, macros.asm is a satellite file (like the headers in C).
† EXTERN
is not a valid directive and generates the error reported
1 For the tech-savvy, it will create an entry 8Ch
in the OMF object file .OBJ generated by TASM.
2 It's code that reason about, and generate, code.
3 For the tech-savvy, EXTRN
makes no sense here since external symbols reduce to a 2/4 bytes offset and a (type) index that contains debug information in the Object Module Format (OMF) used by DOS Object files.
Appendix
This is a bit off-topic and not necessary to answer the question, the reader can stop reading, if it feels overwhelmed, without any loss.
To better grasp the difference between the INCLUDE
ing a symbol and EXTRN
ing it, here is presented the same program that uses an externally defined exit
function instead of a macro.
Library.asm
.8086
.MODEL SMALL
PUBLIC exit
_CODE SEGMENT PARA PUBLIC 'CODE' USE16
ASSUME CS:_CODE, DS:_CODE
exit:
mov ax, 4c00h
int 21h
;No need to ret
_CODE ENDS
;No need for an entry-point
END
Program.asm
.8086
.MODEL SMALL
.STACK 100h
;The type PROC is necessary or TASM will interpret the symbol
;as a variable generating an indirect call! e.g. call [exit]
EXTRN exit:PROC
_CODE SEGMENT PARA PUBLIC 'CODE' USE16
ASSUME CS:_CODE, DS:_CODE
ORG 100h
__START__:
call exit
_CODE ENDS
END __START__
This time both Library.asm and Program.asm must be assembled and the resulting object files must be linked together with TLINK.