home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

C言語系/呼び出し規約/x86/pascal

C言語系/呼び出し規約/x86/pascal

C言語系 / 呼び出し規約 / x86 / pascal
id: 619 所有者: msakamoto-sf    作成日: 2010-03-17 10:32:44
カテゴリ: Assembler C言語 UNIX Windows 

__pascal呼び出し規約:

  • 引数はスタック上にPUSHする。(主に左から右へPUSH)
  • 関数(callee)側でスタックをクリーンアップする。
    • アセンブラレベルではRET imm16命令を使って、戻る時にスタックポインタを"imm16"バイト分だけ戻す。つまり、"imm16"バイト分だけSPが増える(x86ではスタックはアドレスの小さい方へ進んでいくので、「戻る」=SPのアドレス値は大きくなる)。


サンプルコード

callee.c (呼ばれる関数側)

int foo1(int a) { return a * 2; }
int foo2(int a, int b) { return a + b; }
int foo3(int a, int b, int c) { return a + b + c; }
int foo4(int a, int b, int c, int d) { return a + b + c + d; }

caller.c (呼ぶ main() 側)

#include <stdio.h>
 
extern int foo1(int a);
extern int foo2(int a, int b);
extern int foo3(int a, int b, int c);
extern int foo4(int a, int b, int c, int d);
 
int __cdecl main(int argc, char *argv[])
{
    printf("foo1() = %d\n", foo1(10));
    printf("foo2() = %d\n", foo2(10, 20));
    printf("foo3() = %d\n", foo3(10, 20, 30));
    printf("foo4() = %d\n", foo4(10, 20, 30, 40));
    return 0;
}

VC++2008 Express Edtion (obsoleted)

2010年現在、VC++2008では "__pascal" 呼び出し規約はサポートされていない。(obsoleted)

実際に次のようなコード(pascal.c)をコンパイルしようとすると、関数宣言のところでエラーになり、コンパイルに失敗する。

#include <stdio.h>
 
int __pascal foo(int a, int b, int c, int d, int e)
{ return a + b + c + d + e; }
 
int main(int argc, char *argv[]) {
    printf("foo() = %d\n", foo(10, 20, 30, 40, 50));
    return 0;
}

コンパイル→エラー、失敗:

> cl /TC /Od /nologo /c pascal.c
pascal.c
pascal.c(3) : error C2061: 構文エラー : 識別子 'foo'
pascal.c(3) : error C2059: 構文エラー : ';'
pascal.c(3) : error C2059: 構文エラー : '型'

Borland C++ Compiler

指定方法
int __pascal foobar();
typedef int (__pascal *ptr)();
コンパイラオプション
"-p"
装飾名
関数名の英字が全て大文字に変換される。

アセンブラコードを生成

> bcc32 -Od -p -S callee.c
> bcc32 -Od -p -S caller.c

コンパイル&リンク&実行

> bcc32 -Od -p -c -ocallee_pascal.obj callee.c
> bcc32 -Od -p -c -ocaller_pascal.obj caller.c
> ilink32 /c /ap /Tpe c0x32 caller_pascal callee_pascal, pascal, , cw32 import32
> pascal.exe
foo1() = 20
foo2() = 30
foo3() = 60
foo4() = 100

callee.c のアセンブラ出力(callee.asm)

	.386p
	ifdef ??version
	if    ??version GT 500H
	.mmx
	endif
	endif
	model flat
	ifndef	??version
	?debug	macro
	endm
	endif
	?debug	S "callee.c"
	?debug	T "callee.c"
_TEXT	segment dword public use32 'CODE'
_TEXT	ends
_DATA	segment dword public use32 'DATA'
_DATA	ends
_BSS	segment dword public use32 'BSS'
_BSS	ends
DGROUP	group	_BSS,_DATA
_TEXT	segment dword public use32 'CODE'
FOO1	proc	near
?live1@0:
   ;	
   ;	int foo1(int a) { return a * 2; }
   ;	
	push      ebp
	mov       ebp,esp
@1:
	mov       eax,dword ptr [ebp+8]
	add       eax,eax
@3:
@2:
	pop       ebp
	ret       4
FOO1	endp
FOO2	proc	near
?live1@32:
   ;	
   ;	int foo2(int a, int b) { return a + b; }
   ;	
	push      ebp
	mov       ebp,esp
@4:
	mov       eax,dword ptr [ebp+12]
	add       eax,dword ptr [ebp+8]
@6:
@5:
	pop       ebp
	ret       8
FOO2	endp
FOO3	proc	near
?live1@64:
   ;	
   ;	int foo3(int a, int b, int c) { return a + b + c; }
   ;	
	push      ebp
	mov       ebp,esp
@7:
	mov       eax,dword ptr [ebp+16]
	add       eax,dword ptr [ebp+12]
	add       eax,dword ptr [ebp+8]
@9:
@8:
	pop       ebp
	ret       12
FOO3	endp
FOO4	proc	near
?live1@96:
   ;	
   ;	int foo4(int a, int b, int c, int d) { return a + b + c + d; }
   ;	
	push      ebp
	mov       ebp,esp
@10:
	mov       eax,dword ptr [ebp+20]
	add       eax,dword ptr [ebp+16]
	add       eax,dword ptr [ebp+12]
	add       eax,dword ptr [ebp+8]
@12:
@11:
	pop       ebp
	ret       16
FOO4	endp
_TEXT	ends
	public	FOO1
	public	FOO2
	public	FOO3
	public	FOO4
	?debug	D "callee.c" 15473 24064
	end

caller.cのアセンブラ出力(caller.asm)

	.386p
	ifdef ??version
	if    ??version GT 500H
	.mmx
	endif
	endif
	model flat
	ifndef	??version
	?debug	macro
	endm
	endif
	?debug	S "caller.c"
	?debug	T "caller.c"
_TEXT	segment dword public use32 'CODE'
_TEXT	ends
_DATA	segment dword public use32 'DATA'
_DATA	ends
_BSS	segment dword public use32 'BSS'
_BSS	ends
DGROUP	group	_BSS,_DATA
_TEXT	segment dword public use32 'CODE'
_main	proc	near
?live1@0:
   ;	
   ;	int __cdecl main(int argc, char *argv[])
   ;	
	push      ebp
	mov       ebp,esp
   ;	
   ;	{
   ;		printf("foo1() = %d\n", foo1(10));
   ;	
@1:
	push      10
	call      FOO1
	push      eax
	push      offset s@
	call      _printf
	add       esp,8
   ;	
   ;		printf("foo2() = %d\n", foo2(10, 20));
   ;	
	push      10
	push      20
	call      FOO2
	push      eax
	push      offset s@+13
	call      _printf
	add       esp,8
   ;	
   ;		printf("foo3() = %d\n", foo3(10, 20, 30));
   ;	
	push      10
	push      20
	push      30
	call      FOO3
	push      eax
	push      offset s@+26
	call      _printf
	add       esp,8
   ;	
   ;		printf("foo4() = %d\n", foo4(10, 20, 30, 40));
   ;	
	push      10
	push      20
	push      30
	push      40
	call      FOO4
	push      eax
	push      offset s@+39
	call      _printf
	add       esp,8
   ;	
   ;		return 0;
   ;	
	xor       eax,eax
   ;	
   ;	}
   ;	
@3:
@2:
	pop       ebp
	ret 
_main	endp
_TEXT	ends
_DATA	segment dword public use32 'DATA'
s@	label	byte
	;	s@+0:
	db	"foo1() = %d",10,0
	;	s@+13:
	db	"foo2() = %d",10,0
	;	s@+26:
	db	"foo3() = %d",10,0
	;	s@+39:
	db	"foo4() = %d",10,0
	align	4
_DATA	ends
_TEXT	segment dword public use32 'CODE'
_TEXT	ends
	public	_main
 extrn   __setargv__:near
 extrn   _printf:near
 extrn   FOO1:near
 extrn   FOO2:near
 extrn   FOO3:near
 extrn   FOO4:near
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\_nfile.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\_null.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\_defs.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\_stddef.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\stdio.h" 10339 10240
	?debug	D "caller.c" 15473 24232
	end

OpenWatcom Compiler(16bit)

※サンプルコードは C言語系/呼び出し規約/x86/fortran の callee.c, caller.c を使用。

指定方法
int __pascal foobar();
typedef int (__pascal *ptr)();
コンパイラオプション
"-ecp"
装飾名
関数名の英字が全て大文字に変換される。

コンパイル&リンク&実行

> wcc -od -d0 -ecp callee.c
> wcc -od -d0 -ecp caller.c
> wcl -fe=pascal16.exe caller.obj callee.obj
> pascal16.exe
foo1() = 20
foo2() = 30
foo3() = 60
foo4() = 100
foo5() = 150
foo6() = 210

アセンブラ生成

> wdis -a -l=callee.asm callee.obj
> wdis -a -l=caller.asm caller.obj

callee.c のアセンブラ出力(callee.asm)

.387
		PUBLIC	FOO1
		PUBLIC	FOO2
		PUBLIC	FOO3
		PUBLIC	FOO4
		PUBLIC	FOO5
		PUBLIC	FOO6
		EXTRN	__STK:BYTE
		EXTRN	_small_code_:BYTE
DGROUP		GROUP	CONST,CONST2,_DATA
_TEXT		SEGMENT	BYTE PUBLIC USE16 'CODE'
		ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP
FOO1:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 4[bp] 
    shl         ax,1 
    pop         bp 
    ret         2 
FOO2:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 6[bp] 
    add         ax,word ptr 4[bp] 
    pop         bp 
    ret         4 
FOO3:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 8[bp] 
    add         ax,word ptr 6[bp] 
    add         ax,word ptr 4[bp] 
    pop         bp 
    ret         6 
FOO4:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 0aH[bp] 
    add         ax,word ptr 8[bp] 
    add         ax,word ptr 6[bp] 
    add         ax,word ptr 4[bp] 
    pop         bp 
    ret         8 
FOO5:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 0cH[bp] 
    add         ax,word ptr 0aH[bp] 
    add         ax,word ptr 8[bp] 
    add         ax,word ptr 6[bp] 
    add         ax,word ptr 4[bp] 
    pop         bp 
    ret         0aH 
FOO6:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 0eH[bp] 
    add         ax,word ptr 0cH[bp] 
    add         ax,word ptr 0aH[bp] 
    add         ax,word ptr 8[bp] 
    add         ax,word ptr 6[bp] 
    add         ax,word ptr 4[bp] 
    pop         bp 
    ret         0cH 
_TEXT		ENDS
CONST		SEGMENT	WORD PUBLIC USE16 'DATA'
CONST		ENDS
CONST2		SEGMENT	WORD PUBLIC USE16 'DATA'
CONST2		ENDS
_DATA		SEGMENT	WORD PUBLIC USE16 'DATA'
_DATA		ENDS
		END

caller.c のアセンブラ出力(caller.asm)

.387
		PUBLIC	main_
		EXTRN	__STK:BYTE
		EXTRN	FOO1:BYTE
		EXTRN	printf_:BYTE
		EXTRN	FOO2:BYTE
		EXTRN	FOO3:BYTE
		EXTRN	FOO4:BYTE
		EXTRN	FOO5:BYTE
		EXTRN	FOO6:BYTE
		EXTRN	__argc:BYTE
		EXTRN	_small_code_:BYTE
		EXTRN	_cstart_:BYTE
DGROUP		GROUP	CONST,CONST2,_DATA
_TEXT		SEGMENT	BYTE PUBLIC USE16 'CODE'
		ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP
main_:
    push        ax 
    mov         ax,12H 
    call        near ptr __STK 
    pop         ax 
    push        bx 
    push        cx 
    mov         ax,0aH 
    push        ax 
    call        near ptr FOO1 
    push        ax 
    mov         ax,offset DGROUP:L$1 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,0aH 
    push        ax 
    mov         ax,14H 
    push        ax 
    call        near ptr FOO2 
    push        ax 
    mov         ax,offset DGROUP:L$2 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,0aH 
    push        ax 
    mov         ax,14H 
    push        ax 
    mov         ax,1eH 
    push        ax 
    call        near ptr FOO3 
    push        ax 
    mov         ax,offset DGROUP:L$3 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,0aH 
    push        ax 
    mov         ax,14H 
    push        ax 
    mov         ax,1eH 
    push        ax 
    mov         ax,28H 
    push        ax 
    call        near ptr FOO4 
    push        ax 
    mov         ax,offset DGROUP:L$4 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,0aH 
    push        ax 
    mov         ax,14H 
    push        ax 
    mov         ax,1eH 
    push        ax 
    mov         ax,28H 
    push        ax 
    mov         ax,32H 
    push        ax 
    call        near ptr FOO5 
    push        ax 
    mov         ax,offset DGROUP:L$5 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,0aH 
    push        ax 
    mov         ax,14H 
    push        ax 
    mov         ax,1eH 
    push        ax 
    mov         ax,28H 
    push        ax 
    mov         ax,32H 
    push        ax 
    mov         ax,3cH 
    push        ax 
    call        near ptr FOO6 
    push        ax 
    mov         ax,offset DGROUP:L$6 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    xor         ax,ax 
    pop         cx 
    pop         bx 
    ret         
_TEXT		ENDS
CONST		SEGMENT	WORD PUBLIC USE16 'DATA'
L$1:
    DB	66H, 6fH, 6fH, 31H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$2:
    DB	66H, 6fH, 6fH, 32H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$3:
    DB	66H, 6fH, 6fH, 33H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$4:
    DB	66H, 6fH, 6fH, 34H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$5:
    DB	66H, 6fH, 6fH, 35H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$6:
    DB	66H, 6fH, 6fH, 36H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0

CONST		ENDS
CONST2		SEGMENT	WORD PUBLIC USE16 'DATA'
CONST2		ENDS
_DATA		SEGMENT	WORD PUBLIC USE16 'DATA'
_DATA		ENDS
		END

OpenWatcom Compiler(32bit)

※サンプルコードは C言語系/呼び出し規約/x86/fortran の callee.c, caller.c を使用。

指定方法
int __pascal foobar();
typedef int (__pascal *ptr)();
コンパイラオプション
"-ecp"
装飾名
関数名の英字が全て大文字に変換される。

コンパイル&リンク&実行

> wcc386 -od -d0 -ecp callee.c
> wcc386 -od -d0 -ecp caller.c
> wcl386 -fe=pascal32.exe caller.obj callee.obj
> pascal32.exe
foo1() = 20
foo2() = 30
foo3() = 60
foo4() = 100
foo5() = 150
foo6() = 210

アセンブラ生成

> wdis -a -l=callee.asm callee.obj
> wdis -a -l=caller.asm caller.obj

callee.c のアセンブラ出力(callee.asm)

.387
.386p
.model flat
		PUBLIC	FOO1
		PUBLIC	FOO2
		PUBLIC	FOO3
		PUBLIC	FOO4
		PUBLIC	FOO5
		PUBLIC	FOO6
		EXTRN	__CHK:BYTE
DGROUP		GROUP	CONST,CONST2,_DATA
_TEXT		SEGMENT	BYTE PUBLIC USE32 'CODE'
		ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP
FOO1:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 4[esp] 
    add         eax,eax 
    ret         4 
FOO2:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 8[esp] 
    add         eax,dword ptr 4[esp] 
    ret         8 
FOO3:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 0cH[esp] 
    add         eax,dword ptr 8[esp] 
    add         eax,dword ptr 4[esp] 
    ret         0cH 
FOO4:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 10H[esp] 
    add         eax,dword ptr 0cH[esp] 
    add         eax,dword ptr 8[esp] 
    add         eax,dword ptr 4[esp] 
    ret         10H 
FOO5:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 14H[esp] 
    add         eax,dword ptr 10H[esp] 
    add         eax,dword ptr 0cH[esp] 
    add         eax,dword ptr 8[esp] 
    add         eax,dword ptr 4[esp] 
    ret         14H 
FOO6:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 18H[esp] 
    add         eax,dword ptr 14H[esp] 
    add         eax,dword ptr 10H[esp] 
    add         eax,dword ptr 0cH[esp] 
    add         eax,dword ptr 8[esp] 
    add         eax,dword ptr 4[esp] 
    ret         18H 
_TEXT		ENDS
CONST		SEGMENT	DWORD PUBLIC USE32 'DATA'
CONST		ENDS
CONST2		SEGMENT	DWORD PUBLIC USE32 'DATA'
CONST2		ENDS
_DATA		SEGMENT	DWORD PUBLIC USE32 'DATA'
_DATA		ENDS
		END

caller.c のアセンブラ出力(caller.asm)

.387
.386p
.model flat
		PUBLIC	main_
		EXTRN	__CHK:BYTE
		EXTRN	FOO1:BYTE
		EXTRN	printf_:BYTE
		EXTRN	FOO2:BYTE
		EXTRN	FOO3:BYTE
		EXTRN	FOO4:BYTE
		EXTRN	FOO5:BYTE
		EXTRN	FOO6:BYTE
		EXTRN	__argc:BYTE
		EXTRN	_cstart_:BYTE
DGROUP		GROUP	CONST,CONST2,_DATA
_TEXT		SEGMENT	BYTE PUBLIC USE32 'CODE'
		ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP
main_:
    push        24H 
    call        near ptr FLAT:__CHK 
    push        ebx 
    push        ecx 
    push        0aH 
    call        near ptr FLAT:FOO1 
    push        eax 
    push        offset FLAT:L$1 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        0aH 
    push        14H 
    call        near ptr FLAT:FOO2 
    push        eax 
    push        offset FLAT:L$2 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        0aH 
    push        14H 
    push        1eH 
    call        near ptr FLAT:FOO3 
    push        eax 
    push        offset FLAT:L$3 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        0aH 
    push        14H 
    push        1eH 
    push        28H 
    call        near ptr FLAT:FOO4 
    push        eax 
    push        offset FLAT:L$4 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        0aH 
    push        14H 
    push        1eH 
    push        28H 
    push        32H 
    call        near ptr FLAT:FOO5 
    push        eax 
    push        offset FLAT:L$5 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        0aH 
    push        14H 
    push        1eH 
    push        28H 
    push        32H 
    push        3cH 
    call        near ptr FLAT:FOO6 
    push        eax 
    push        offset FLAT:L$6 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    xor         eax,eax 
    pop         ecx 
    pop         ebx 
    ret         
_TEXT		ENDS
CONST		SEGMENT	DWORD PUBLIC USE32 'DATA'
L$1:
    DB	66H, 6fH, 6fH, 31H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$2:
    DB	66H, 6fH, 6fH, 32H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$3:
    DB	66H, 6fH, 6fH, 33H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$4:
    DB	66H, 6fH, 6fH, 34H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$5:
    DB	66H, 6fH, 6fH, 35H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0
L$6:
    DB	66H, 6fH, 6fH, 36H, 28H, 29H, 20H, 3dH
    DB	20H, 25H, 64H, 0aH, 0

CONST		ENDS
CONST2		SEGMENT	DWORD PUBLIC USE32 'DATA'
CONST2		ENDS
_DATA		SEGMENT	DWORD PUBLIC USE32 'DATA'
_DATA		ENDS
		END

Turbo C++ 4.0J(TC4J)

TC4Jで、コマンドラインからの呼び出し規約指定オプションが不明だった為、gcc系列と同様、CALLINGCONVを"-D"でdefineすることにより切り替える方式を採った。
なお、TC4Jについてはリンク&実行までは行っていない。

指定方法
int __pascal foobar();
typedef int (__pascal *ptr)();
装飾名
関数名の英字が全て大文字に変換される。

アセンブラコードを生成

> tcc -DCALLINGCONV=__pascal -S callee.c
> tcc -DCALLINGCONV=__pascal -S caller.c

callee.c のアセンブラ出力(callee.asm)

	.286p
	ifndef	??version
?debug	macro
	endm
publicdll macro	name
	public	name
	endm
$comm	macro	name,dist,size,count
	comm	dist name:BYTE:count*size
	endm
	else
$comm	macro	name,dist,size,count
	comm	dist name[size]:BYTE:count
	endm
	endif
	?debug	V 301h
	?debug	S "callee.c"
	?debug	C E91593723C0863616C6C65652E63
_TEXT	segment byte public 'CODE'
_TEXT	ends
DGROUP	group	_DATA,_BSS
	assume	cs:_TEXT,ds:DGROUP
_DATA	segment word public 'DATA'
d@	label	byte
d@w	label	word
_DATA	ends
_BSS	segment word public 'BSS'
b@	label	byte
b@w	label	word
_BSS	ends
_TEXT	segment byte public 'CODE'
   ;	
   ;	int CALLINGCONV foo1(int a) { return a * 2; }
   ;	
	assume	cs:_TEXT,ds:DGROUP
FOO1	proc	near
	push	bp
	mov	bp,sp
	mov	ax,word ptr [bp+4]
	add	ax,ax
	pop	bp
	ret	2
	pop	bp
	ret	2
FOO1	endp
   ;	
   ;	int CALLINGCONV foo2(int a, int b) { return a + b; }
   ;	
	assume	cs:_TEXT,ds:DGROUP
FOO2	proc	near
	push	bp
	mov	bp,sp
	mov	ax,word ptr [bp+6]
	add	ax,word ptr [bp+4]
	pop	bp
	ret	4
	pop	bp
	ret	4
FOO2	endp
   ;	
   ;	int CALLINGCONV foo3(int a, int b, int c) { return a + b + c; }
   ;	
	assume	cs:_TEXT,ds:DGROUP
FOO3	proc	near
	push	bp
	mov	bp,sp
	mov	ax,word ptr [bp+8]
	add	ax,word ptr [bp+6]
	add	ax,word ptr [bp+4]
	pop	bp
	ret	6
	pop	bp
	ret	6
FOO3	endp
   ;	
   ;	int CALLINGCONV foo4(int a, int b, int c, int d) { return a + b + c + d; }
   ;	
	assume	cs:_TEXT,ds:DGROUP
FOO4	proc	near
	push	bp
	mov	bp,sp
	mov	ax,word ptr [bp+10]
	add	ax,word ptr [bp+8]
	add	ax,word ptr [bp+6]
	add	ax,word ptr [bp+4]
	pop	bp
	ret	8
	pop	bp
	ret	8
FOO4	endp
	?debug	C E9
	?debug	C FA00000000
_TEXT	ends
_DATA	segment word public 'DATA'
s@	label	byte
_DATA	ends
_TEXT	segment byte public 'CODE'
_TEXT	ends
_s@	equ	s@
	public	FOO1
	public	FOO2
	public	FOO3
	public	FOO4
	end

caller.c のアセンブラ出力(caller.asm)

	.286p
	ifndef	??version
?debug	macro
	endm
publicdll macro	name
	public	name
	endm
$comm	macro	name,dist,size,count
	comm	dist name:BYTE:count*size
	endm
	else
$comm	macro	name,dist,size,count
	comm	dist name[size]:BYTE:count
	endm
	endif
	?debug	V 301h
	?debug	S "caller.c"
	?debug	C E9D2A0723C0863616C6C65722E63
	?debug	C E900207F1E16433A5C5443345C494E434C5544455C737464696F2E+
	?debug	C 68
	?debug	C E900207F1E16433A5C5443345C494E434C5544455C5F646566732E+
	?debug	C 68
	?debug	C E900207F1E17433A5C5443345C494E434C5544455C5F6E66696C65+
	?debug	C 2E68
	?debug	C E900207F1E16433A5C5443345C494E434C5544455C5F6E756C6C2E+
	?debug	C 68
_TEXT	segment byte public 'CODE'
_TEXT	ends
DGROUP	group	_DATA,_BSS
	assume	cs:_TEXT,ds:DGROUP
_DATA	segment word public 'DATA'
d@	label	byte
d@w	label	word
_DATA	ends
_BSS	segment word public 'BSS'
b@	label	byte
b@w	label	word
_BSS	ends
_TEXT	segment byte public 'CODE'
   ;	
   ;	int __cdecl main(int argc, char *argv[])
   ;	
	assume	cs:_TEXT,ds:DGROUP
_main	proc	near
	push	bp
	mov	bp,sp
   ;	
   ;	{
   ;	    printf("foo1() = %d\n", foo1(10));
   ;	
	push	10
	call	near ptr FOO1
	push	ax
	push	offset DGROUP:s@
	call	near ptr _printf
	add	sp,4
   ;	
   ;	    printf("foo2() = %d\n", foo2(10, 20));
   ;	
	push	10
	push	20
	call	near ptr FOO2
	push	ax
	push	offset DGROUP:s@+13
	call	near ptr _printf
	add	sp,4
   ;	
   ;	    printf("foo3() = %d\n", foo3(10, 20, 30));
   ;	
	push	10
	push	20
	push	30
	call	near ptr FOO3
	push	ax
	push	offset DGROUP:s@+26
	call	near ptr _printf
	add	sp,4
   ;	
   ;	    printf("foo4() = %d\n", foo4(10, 20, 30, 40));
   ;	
	push	10
	push	20
	push	30
	push	40
	call	near ptr FOO4
	push	ax
	push	offset DGROUP:s@+39
	call	near ptr _printf
	add	sp,4
   ;	
   ;	    return 0;
   ;	
	xor	ax,ax
	pop	bp
	ret	
   ;	
   ;	}
   ;	
	pop	bp
	ret	
_main	endp
	?debug	C E9
	?debug	C FA00000000
_TEXT	ends
_DATA	segment word public 'DATA'
s@	label	byte
	db	'foo1() = %d'
	db	10
	db	0
	db	'foo2() = %d'
	db	10
	db	0
	db	'foo3() = %d'
	db	10
	db	0
	db	'foo4() = %d'
	db	10
	db	0
_DATA	ends
_TEXT	segment byte public 'CODE'
_TEXT	ends
_s@	equ	s@
	extrn	_printf:near
	extrn	FOO1:near
	extrn	FOO2:near
	extrn	FOO3:near
	extrn	FOO4:near
	public	_main
	extrn	__setargv__:far
	end


プレーンテキスト形式でダウンロード
現在のバージョン : 6
更新者: msakamoto-sf
更新日: 2010-03-19 17:17:18
md5:b5fc5e66d0d2a3713f69657e2304d9df
sha1:4c2e2f78a4d438c00a8a1ae95d58de882e0affd1
コメント
コメントを投稿するにはログインして下さい。