PROC and ENDP are assembler directives, not instructions: they produce no code of their own. name PROC defines name as a code label and records whether it is NEAR or FAR. MASM uses that in two places: a CALL name becomes a near or far call, and every RET between PROC and ENDP becomes a near or far return. Without NEAR or FAR, the distance follows the .MODEL: NEAR for TINY, SMALL and COMPACT, FAR for MEDIUM, LARGE and HUGE.

MOV AL, 1
CALL SHOWD1
MOV AL, 2
CALL SHOWD1
MOV AL, 3
CALL SHOWD1 ; prints 123
SHOWD1 PROC NEAR ; print AL as a digit; keeps AX and DX
PUSH AX
PUSH DX
ADD AL, "0"
MOV DL, AL
MOV AH, 02h
INT 21h
POP DX
POP AX
RET
SHOWD1 ENDP

Pitfalls

PROC is not a wall: if the program runs into it from above, the CPU executes it like any other code, and its RET then pops a random word. Place procedures after the exit, as here, or jump over them. ENDP does not return either; a missing RET falls through into whatever follows. The name on ENDP must match the one on PROC. In MASM 6 a label with one colon inside a procedure is local to it, so two procedures may each have a DONE1:; write DONE1:: to make one visible outside.

MASM extras

MASM 6 accepts more on the PROC line. USES SI DI saves and restores the listed registers, and with a language type, parameters can be named so MASM writes the BP frame for you. This guide writes frames by hand (see Stack frames) so every instruction is visible.

FAR1 PROC FAR ; called with CALL FAR PTR; RET becomes RETF
RET
FAR1 ENDP
SUM2 PROC NEAR C, A1:WORD, B1:WORD
MOV AX, A1 ; MASM reads [BP+4]
ADD AX, B1 ; and [BP+6]
RET ; MASM adds POP BP before it
SUM2 ENDP