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

C言語系/呼び出し規約/x86/"PASCAL" (v1)

C言語系/呼び出し規約/x86/"PASCAL" (v1)

C言語系 / 呼び出し規約 / x86 / "PASCAL" (v1)
id: 626 所有者: msakamoto-sf    作成日: 2010-03-17 17:25:54
カテゴリ: Assembler C言語 Windows 

"PASCAL"はヘッダーファイルで定義された呼び出し規約で、"__pascal"呼び出し規約のことではない。
実際にどの呼び出し規約("__stdcall", "__cdecl", "__pascal", ...)になるかは、OS/コンパイラによって異なってくるので、使用する場合は注意が必要。

ただし、2010年現在の Win32 APIプラットフォームにおいては基本的に PASCAL == "__stdcall" と考えて良い。
VC++2008, Borland C++ Compiler共に、PASCALは"__stdcall"にdefineされている。



サンプルコード(big_pascal.c)

VC++2008/Borland C++ Compilerで "PASCAL" を使うには、Windows用のヘッダーファイルをincludeする必要がある。今回は "windows.h" をincludeした。
windows.hをincludeしない場合、VC++2008/Borland C++ Compilerの両方で関数宣言の構文エラーとなりコンパイルに失敗する。

#include <stdio.h>
#include <windows.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;
}

VC++2008 Express Edtion (obsoleted)

プリプロセス結果およびアセンブラ出力から、"PASCAL" は "__stdcall" にdefineされている事が分かる。
MSDN上では "obsoleted" となっており、"WINAPI"の方を使うよう推奨されている。

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

> cl /FAs /TC /Od /nologo /c big_pascal.c
> link /SUBSYSTEM:CONSOLE /NOLOGO /OUT:big_pascal.exe big_pascal.obj
> big_pascal.exe
foo() = 150

プリプロセス結果を生成:

> cl /P /TC /Od /nologo /c big_pascal.c

プリプロセス結果:

#line 3 "big_pascal.c"
 
int __stdcall 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;
}

アセンブラ出力(big_pascal.asm)

; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 

	TITLE	C:\in_vitro\c\cc_vc\big_pascal.c
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

_DATA	SEGMENT
$SG78588 DB	'foo() = %d', 0aH, 00H
_DATA	ENDS
PUBLIC	_foo@20
; Function compile flags: /Odtp
; File c:\in_vitro\c\cc_vc\big_pascal.c
_TEXT	SEGMENT
_a$ = 8							; size = 4
_b$ = 12						; size = 4
_c$ = 16						; size = 4
_d$ = 20						; size = 4
_e$ = 24						; size = 4
_foo@20	PROC

; 5    : { return a + b + c + d + e; }

	push	ebp
	mov	ebp, esp
	mov	eax, DWORD PTR _a$[ebp]
	add	eax, DWORD PTR _b$[ebp]
	add	eax, DWORD PTR _c$[ebp]
	add	eax, DWORD PTR _d$[ebp]
	add	eax, DWORD PTR _e$[ebp]
	pop	ebp
	ret	20					; 00000014H
_foo@20	ENDP
_TEXT	ENDS
PUBLIC	_main
EXTRN	_printf:PROC
; Function compile flags: /Odtp
_TEXT	SEGMENT
_argc$ = 8						; size = 4
_argv$ = 12						; size = 4
_main	PROC

; 7    : int main(int argc, char *argv[]) {

	push	ebp
	mov	ebp, esp

; 8    : 	printf("foo() = %d\n", foo(10, 20, 30, 40, 50));

	push	50					; 00000032H
	push	40					; 00000028H
	push	30					; 0000001eH
	push	20					; 00000014H
	push	10					; 0000000aH
	call	_foo@20
	push	eax
	push	OFFSET $SG78588
	call	_printf
	add	esp, 8

; 9    : 	return 0;

	xor	eax, eax

; 10   : }

	pop	ebp
	ret	0
_main	ENDP
_TEXT	ENDS
END

Borland C++ Compiler

プリプロセス結果およびアセンブラ出力から、"PASCAL" は "__stdcall" にdefineされている事が分かる。

アセンブラコードを生成

> bcc32 -S big_pascal.c

コンパイル&実行

> bcc32 big_pascal.c
> big_pascal.exe
foo() = 150

プリプロセス結果を生成:

> cpp32 big_pascal.c

プリプロセス結果:

/* big_pascal.c 3: */
/* big_pascal.c 4: */int __stdcall foo(int a, int b, int c, int d, int e)
/* big_pascal.c 5: */{ return a + b + c + d + e; }
/* big_pascal.c 6: */
/* big_pascal.c 7: */int main(int argc, char *argv[]) {
/* big_pascal.c 8: */printf("foo() = %d\n", foo(10, 20, 30, 40, 50));
/* big_pascal.c 9: */return 0;
/* big_pascal.c 10: */}

アセンブラ出力(big_pascal.asm)

	.386p
	ifdef ??version
	if    ??version GT 500H
	.mmx
	endif
	endif
	model flat
	ifndef	??version
	?debug	macro
	endm
	endif
	?debug	S "big_pascal.c"
	?debug	T "big_pascal.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'
foo	proc	near
?live1@0:
   ;	
   ;	int PASCAL foo(int a, int b, int c, int d, int e)
   ;	
	push      ebp
	mov       ebp,esp
   ;	
   ;	{ return a + b + c + d + e; }
   ;	
@1:
	mov       eax,dword ptr [ebp+8]
	add       eax,dword ptr [ebp+12]
	add       eax,dword ptr [ebp+16]
	add       eax,dword ptr [ebp+20]
	add       eax,dword ptr [ebp+24]
@3:
@2:
	pop       ebp
	ret       20
foo	endp
_main	proc	near
?live1@48:
   ;	
   ;	int main(int argc, char *argv[]) {
   ;	
	push      ebp
	mov       ebp,esp
   ;	
   ;		printf("foo() = %d\n", foo(10, 20, 30, 40, 50));
   ;	
@4:
	push      50
	push      40
	push      30
	push      20
	push      10
	call      foo
	push      eax
	push      offset s@
	call      _printf
	add       esp,8
   ;	
   ;		return 0;
   ;	
	xor       eax,eax
   ;	
   ;	}
   ;	
@6:
@5:
	pop       ebp
	ret 
_main	endp
_TEXT	ends
_DATA	segment dword public use32 'DATA'
s@	label	byte
	;	s@+0:
	db	"foo() = %d",10,0
	align	4
_DATA	ends
_TEXT	segment dword public use32 'CODE'
_TEXT	ends
	public	foo
	public	_main
 extrn   __setargv__:near
 extrn   _printf:near
 ?debug  C 9F757569642E6C6962
 ?debug  C 9F757569642E6C6962
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\imm.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\mcx.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winsvc.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\commdlg.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\oleauto.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\propidl.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\oaidl.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\msxml.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\servprov.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\oleidl.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\urlmon.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\cguid.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\objidl.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\unknwn.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\search.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\stdlib.h" 10521 10272
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\objbase.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\ole2.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\prsht.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winspool.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winsmcrd.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winioctl.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\rpcnsip.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\rpcndr.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\wtypes.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winscard.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winefs.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\wincrypt.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\qos.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winsock2.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winperf.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\shellapi.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\rpcasync.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\rpcnterr.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\rpcnsi.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\rpcdcep.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\rpcdce.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\rpc.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\nb30.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\mmsystem.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\lzexpand.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\dlgs.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\ddeml.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\dde.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\cderr.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winnetwk.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winreg.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winver.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\wincon.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winnls.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\tvout.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winuser.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\pshpack1.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\wingdi.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winerror.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winbase.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\pshpack8.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\pshpack2.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\poppack.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\pshpack4.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\mem.h" 10521 10272
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\_loc.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\locale.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\_str.h" 10521 10272
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\string.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\guiddef.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\basetsd.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\mbctype.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\ctype.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\winnt.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\windef.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\stdarg.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\excpt.h" 10339 10240
	?debug	D "C:\in_vitro\apps\borland\bcc55\include\windows.h" 10339 10240
	?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 "big_pascal.c" 15473 34993
	end

MinGW/MSYS

OpenWatcom Compiler(16bit)

OpenWatcom Compiler(32bit)

Turbo C++ 4.0J

GCC4.1.2 + binutils-2.7.50.0.6 (CentOS5.2)



プレーンテキスト形式でダウンロード
表示中のバージョン : 1
現在のバージョン : 3
更新者: msakamoto-sf
更新日: 2010-03-19 20:13:04
md5:c9a1e027194f883014ac6cd5be36ec78
sha1:c5a3cc47560638bdb0d92b3729303cbd360cfae5
コメント
コメントを投稿するにはログインして下さい。