PROC / ENDP

PROC 文と ENDP 文は、それぞれプロシージャ(手続き、サブルーチン)の開始と終了を宣言します。PROC と ENDP 文は、プログラムを作成するうえで必須ではありませんが、大きなプログラムでは読みやすいコードを作成するうえで効果があります。

構文    label    PROC    [type][lang][scope][USES regs ... ,][args,...]
    label    ENDP
各 args の構文   name[[num]][:type]
例    SUBR    PROC
        RET
    SUBR    ENDP
    MYPRC    PROC    FAR PUBLIC USES AX SI, ARG1[10]:BYTE, ARG2:NEAR PTR
        MOV    AL, ARG1[2]
        MOV    SI, ARG2
        MOV    BYTE PTR [SI], AL
        RET
    MYPRC    ENDP

対応する PROC 文と ENDP 文には、同じ label 名を指定する必要があります。label はタイプ type のラベルとして定義されます。

type には、「NEAR」「FAR」「PROC」のいずれかを指定します。デフォルトは「PROC」です。type により、label のタイプと、プロシージャ内の RET 命令が RETN と RETF のどちらになるかが決まります。

lang には、言語モデルを指定します。これにより、プロシージャ名や引数の位置などの呼び出し規約が決まります。

scope には、「PRIVATE」または「PUBLIC」を指定します。デフォルトは PRIVATE です。PUBLIC を指定すると、label を PUBLIC 文で宣言するのと同等の効果があります。PUBLIC を指定した場合は、PUBLIC 文と同様に、続けて「AS as_name」を指定して外部公開名を変更できます。

regs には、16 ビットまたは 32 ビットレジスタ名を空白で区切って指定します。ここに指定したレジスタは、プロシージャの先頭でスタックにプッシュされ、プロシージャ内の RET 命令の直前でポップされます。つまり、そのために必要なコードが自動的に生成されます。RETN 命令、RETF 命令、およびオペランド付きの RET 命令については、ポップ命令は生成されません。

引数の宣言

PROC 文では、スタック経由でプロシージャに渡される引数を宣言できます。これは、スタック上の引数に簡単にアクセスするための機能です。引数を宣言する場合は、args を指定します。args には、プロシージャに渡される引数をカンマ(,)で区切って指定します。これにより、スタックに積まれた引数を簡単に参照できるようになります。

args を指定すると、 BP(EBP)レジスタに「スタック フレーム」の値を設定するコードが自動的に生成されます。引数を参照しないプロシージャには args を指定しない方が効率的です。

args で宣言したラベルへの参照は、 BP(EBP)レジスタ相対アドレス参照に置き換えられます。そのため、args を使用するプロシージャ内では、 BP(EBP)レジスタの値を変えずに維持する必要があります。また、args で定義したラベルは、 BP(EBP)レジスタ相対アドレス参照を使用できる命令でのみ使用できます。

; ソースコード
p    proc    arg:word
    mov    arg, 7
    add    arg, ax
    ret
p    endp
; 生成コード(アセンブルリスト)
p    PROC    NEAR
    push    bp    ;-0000  55
    mov    bp,sp    ;-0001  8B EC
    add    sp,-2h    ;-0003  83 C4 FE
    mov    WORD PTR [bp+4h],7h    ; 0006  C7 46 04 07 00 (arg)
    add    WORD PTR [bp+4h],ax    ; 000B  01 46 04 (arg)
    mov    sp,bp    ;-000E  8B E5
    pop    bp    ;-0010  5D
    retn        ; 0011  C3
p    ENDP

参照 ラベルPROTOINVOKE

[目次]