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

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

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

C言語系 / 呼び出し規約 / x86 / syscall
id: 623 所有者: msakamoto-sf    作成日: 2010-03-17 13:06:39
カテゴリ: Assembler C言語 Windows 

sysycall呼び出し規約は、OS/2 の 32bit API で使われていた。
Linux/BSDでのsyscall(2)とは無関係。

2010年の時点のMSDNによると、現在は "__syscall" 呼び出し規約はサポートされていない。(obsoleted)

OpenWatcom 1.8 においては、現在もサポートされている。(2010年3月時点)

  • 関数名の装飾は無し。
  • 引数は右か左へスタックにPUSHされる。
  • スタッククリーンアップは関数を呼ぶ側(caller)で実現する。

OpenWatcom 1.8 User's manual より:

__syscall (32-bit only)

The __syscall keyword may be used with function definitions, and indicates that the calling convention used is compatible with functions provided by 32-bit OS/2.
Notes:

  1. Symbols names are not modified, that is, they are not adorned with leading or trailing underscores.
  2. Arguments are pushed on the stack from right to left. That is, the last argument is pushed first. The calling routine will remove the arguments from the stack.
  3. When a structure is returned, the caller allocates space on the stack. The address of the allocated space will be pushed on the stack immediately before the call instruction. Upon returning from the call, register EAX will contain address of the space allocated for the return value. Floating-point values are returned in 80x87 register ST(0).
  4. Registers EAX, ECX and EDX are not saved and restored when a call is made.


サンプルコード

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; }
int foo5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
int foo6(int a, int b, int c, int d, int e, int f) { return a + b + c + d + e + f; }

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);
extern int foo5(int a, int b, int c, int d, int e);
extern int foo6(int a, int b, int c, int d, int e, int f);
 
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));
    printf("foo5() = %d\n", foo5(10, 20, 30, 40, 50));
    printf("foo6() = %d\n", foo6(10, 20, 30, 40, 50, 60));
    return 0;
}

OpenWatcom Compiler(16bit)

指定方法
int __syscall foobar();
typedef int (__syscall *ptr)();
コンパイラオプション
"-ecs"
装飾名
装飾無し。

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

> wcc -od -d0 -ecs callee.c
> wcc -od -d0 -ecs caller.c
> wcl -fe=syscall16.exe caller.obj callee.obj
> syscall16.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         
foo2:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 4[bp] 
    add         ax,word ptr 6[bp] 
    pop         bp 
    ret         
foo3:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 4[bp] 
    add         ax,word ptr 6[bp] 
    add         ax,word ptr 8[bp] 
    pop         bp 
    ret         
foo4:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 4[bp] 
    add         ax,word ptr 6[bp] 
    add         ax,word ptr 8[bp] 
    add         ax,word ptr 0aH[bp] 
    pop         bp 
    ret         
foo5:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 4[bp] 
    add         ax,word ptr 6[bp] 
    add         ax,word ptr 8[bp] 
    add         ax,word ptr 0aH[bp] 
    add         ax,word ptr 0cH[bp] 
    pop         bp 
    ret         
foo6:
    mov         ax,4 
    call        near ptr __STK 
    push        bp 
    mov         bp,sp 
    mov         ax,word ptr 4[bp] 
    add         ax,word ptr 6[bp] 
    add         ax,word ptr 8[bp] 
    add         ax,word ptr 0aH[bp] 
    add         ax,word ptr 0cH[bp] 
    add         ax,word ptr 0eH[bp] 
    pop         bp 
    ret         
_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 
    add         sp,2 
    push        ax 
    mov         ax,offset DGROUP:L$1 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,14H 
    push        ax 
    mov         ax,0aH 
    push        ax 
    call        near ptr foo2 
    add         sp,4 
    push        ax 
    mov         ax,offset DGROUP:L$2 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,1eH 
    push        ax 
    mov         ax,14H 
    push        ax 
    mov         ax,0aH 
    push        ax 
    call        near ptr foo3 
    add         sp,6 
    push        ax 
    mov         ax,offset DGROUP:L$3 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,28H 
    push        ax 
    mov         ax,1eH 
    push        ax 
    mov         ax,14H 
    push        ax 
    mov         ax,0aH 
    push        ax 
    call        near ptr foo4 
    add         sp,8 
    push        ax 
    mov         ax,offset DGROUP:L$4 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,32H 
    push        ax 
    mov         ax,28H 
    push        ax 
    mov         ax,1eH 
    push        ax 
    mov         ax,14H 
    push        ax 
    mov         ax,0aH 
    push        ax 
    call        near ptr foo5 
    add         sp,0aH 
    push        ax 
    mov         ax,offset DGROUP:L$5 
    push        ax 
    call        near ptr printf_ 
    add         sp,4 
    mov         ax,3cH 
    push        ax 
    mov         ax,32H 
    push        ax 
    mov         ax,28H 
    push        ax 
    mov         ax,1eH 
    push        ax 
    mov         ax,14H 
    push        ax 
    mov         ax,0aH 
    push        ax 
    call        near ptr foo6 
    add         sp,0cH 
    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)

指定方法
int __syscall foobar();
typedef int (__syscall *ptr)();
コンパイラオプション
"-ecs"
装飾名
装飾無し。

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

> wcc386 -od -d0 -ecs callee.c
> wcc386 -od -d0 -ecs caller.c
> wcl386 -fe=syscall32.exe caller.obj callee.obj
> syscall32.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         
foo2:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 4[esp] 
    add         eax,dword ptr 8[esp] 
    ret         
foo3:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 4[esp] 
    add         eax,dword ptr 8[esp] 
    add         eax,dword ptr 0cH[esp] 
    ret         
foo4:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 4[esp] 
    add         eax,dword ptr 8[esp] 
    add         eax,dword ptr 0cH[esp] 
    add         eax,dword ptr 10H[esp] 
    ret         
foo5:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 4[esp] 
    add         eax,dword ptr 8[esp] 
    add         eax,dword ptr 0cH[esp] 
    add         eax,dword ptr 10H[esp] 
    add         eax,dword ptr 14H[esp] 
    ret         
foo6:
    push        4 
    call        near ptr FLAT:__CHK 
    mov         eax,dword ptr 4[esp] 
    add         eax,dword ptr 8[esp] 
    add         eax,dword ptr 0cH[esp] 
    add         eax,dword ptr 10H[esp] 
    add         eax,dword ptr 14H[esp] 
    add         eax,dword ptr 18H[esp] 
    ret         
_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        20H 
    call        near ptr FLAT:__CHK 
    push        ecx 
    push        0aH 
    call        near ptr FLAT:foo1 
    add         esp,4 
    push        eax 
    push        offset FLAT:L$1 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        14H 
    push        0aH 
    call        near ptr FLAT:foo2 
    add         esp,8 
    push        eax 
    push        offset FLAT:L$2 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        1eH 
    push        14H 
    push        0aH 
    call        near ptr FLAT:foo3 
    add         esp,0cH 
    push        eax 
    push        offset FLAT:L$3 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        28H 
    push        1eH 
    push        14H 
    push        0aH 
    call        near ptr FLAT:foo4 
    add         esp,10H 
    push        eax 
    push        offset FLAT:L$4 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        32H 
    push        28H 
    push        1eH 
    push        14H 
    push        0aH 
    call        near ptr FLAT:foo5 
    add         esp,14H 
    push        eax 
    push        offset FLAT:L$5 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    push        3cH 
    push        32H 
    push        28H 
    push        1eH 
    push        14H 
    push        0aH 
    call        near ptr FLAT:foo6 
    add         esp,18H 
    push        eax 
    push        offset FLAT:L$6 
    call        near ptr FLAT:printf_ 
    add         esp,8 
    xor         eax,eax 
    pop         ecx 
    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


プレーンテキスト形式でダウンロード
現在のバージョン : 2
更新者: msakamoto-sf
更新日: 2010-03-19 16:48:39
md5:7c15b77715dc8e19177611466ec1bd41
sha1:6623fe458b6864839afdb29fc99aebf43b30cc93
コメント
コメントを投稿するにはログインして下さい。