⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccall.gml

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 GML
📖 第 1 页 / 共 4 页
字号:
.note
All used 80x86 registers except registers EAX, ECX and EDX must be saved on
entry and restored on exit.
Segment registers DS and ES must also be saved on entry and restored on
exit.
Segment register ES does not have to be saved and restored when using a
memory model that is not a small data model.
.ix 'options' 'r'
Note that segment registers only have to be saved and restored if you are
compiling your application with the "r" option.
.note
The direction flag must be clear before returning to the caller.
.note
In a small code model,
any segment containing executable code must belong to the segment "_TEXT"
and the class "CODE".
The segment "_TEXT" must have a "combine" type of "PUBLIC".
On entry, CS contains the segment address of the segment "_TEXT".
In a big code model there is no restriction on the naming of segments
which contain executable code.
.note
In a small data model, segment register DS contains the segment address
of the group "DGROUP".
This is not the case in a big data model.
.note
When writing assembly language functions for the small code model, you
must declare them as "near".
If you wish to write assembly language functions for the big code model,
you must declare them as "far".
.note
In general, when naming segments for your code or data,
you should follow the conventions described in the section entitled
"Memory Layout" in this chapter.
.note
The caller is responsible for removing arguments from the stack.
.endnote
.do end
.*
.section Functions with Variable Number of Arguments
.*
.np
.ix 'variable argument lists'
A function prototype with a parameter list that ends with ",..."
has a variable number of arguments.
In this case, all arguments are passed on the stack.
Since no prototyping information exists for arguments represented by
",...", those arguments are passed as described in the section
"Passing Arguments".
.*
.section Returning Values from Functions
.*
.np
The way in which function values are returned depends on the size of
the return value.
The following examples describe how function values are to be returned.
They are coded for a small code model.
.ix 'functions' 'returning values'
.ix 'returning values from functions'
.autonote
.note
1-byte values are to be returned in register AL.
.exam begin
_TEXT   segment byte public 'CODE'
        assume  CS:_TEXT
        public  Ret1_
Ret1_   proc    near   ; char Ret1()
        mov     AL,'G'
        ret
Ret1_   endp
_TEXT   ends
        end
.exam end
.note
2-byte values are to be returned in register AX.
.exam begin
_TEXT   segment byte public 'CODE'
        assume  CS:_TEXT
        public  Ret2_
Ret2_   proc    near   ; short int Ret2()
        mov     AX,77
        ret
Ret2_   endp
_TEXT   ends
        end
.exam end
.if '&machine' eq '8086' .do begin
.note
4-byte values are to be returned in registers DX and AX with the most
significant word in register DX.
.exam begin
_TEXT   segment byte public 'CODE'
        assume  CS:_TEXT
        public  Ret4_
Ret4_   proc    near   ; long int Ret4()
        mov     AX,word ptr CS:Val4+0
        mov     DX,word ptr CS:Val4+2
        ret
Val4    dd      7777777
Ret4_   endp
_TEXT   ends
        end
.exam end
.note
8-byte values, except structures, are to be returned in registers AX, BX,
CX and DX with the most significant word in register AX.
.exam begin
        .8087
_TEXT   segment byte public 'CODE'
        assume  CS:_TEXT
        public  Ret8_
Ret8_   proc    near   ; double Ret8()
        mov     DX,word ptr CS:Val8+0
        mov     CX,word ptr CS:Val8+2
        mov     BX,word ptr CS:Val8+4
        mov     AX,word ptr CS:Val8+6
        ret
Val8:   dq      7.7
Ret8_   endp
_TEXT   ends
        end
.exam end
.np
The ".8087" pseudo-op must be specified so that all floating-point
constants are generated in 8087 format.
When using the "fpc" (floating-point calls) option, "float" and "double"
are returned in registers.
See section "Returning Values in 80x87-based Applications" when using
the "fpi" or "fpi87" options.
.do end
.el .do begin
.note
4-byte values are to be returned in register EAX.
.exam begin
_TEXT   segment byte public 'CODE'
        assume  CS:_TEXT
        public  Ret4_
Ret4_   proc    near   ; int Ret4()
        mov     EAX,7777777
        ret
Ret4_   endp
_TEXT   ends
        end
.exam end
.note
8-byte values, except structures, are to be returned in registers
EDX and EAX.
When using the "fpc" (floating-point calls) option, "float" and "double"
are returned in registers.
See section "Returning Values in 80x87-based Applications" when using
the "fpi" or "fpi87" options.
.exam begin
        .8087
_TEXT   segment byte public 'CODE'
        assume  CS:_TEXT
        public  Ret8_
Ret8_   proc    near   ; double Ret8()
        mov     EDX,dword ptr CS:Val8+4
        mov     EAX,dword ptr CS:Val8
        ret
Val8:   dq      7.7
Ret8_   endp
_TEXT   ends
        end
.exam end
.np
The ".8087" pseudo-op must be specified so that all floating-point
constants are generated in 8087 format.
.do end
.note
Otherwise, the caller allocates space on the stack for the return value
and sets register &siup to point to this area.
In a big data model, register &siup contains an offset relative
to the segment value in segment register SS.
.if '&machine' eq '8086' .do begin
:set symbol="word" value="word".
.do end
.el .do begin
:set symbol="word" value="dword".
.do end
.cp 19
.exam begin
_TEXT   segment byte public 'CODE'
        assume  CS:_TEXT
        public  RetX_
;
; struct int_values {
;     int value1, value2, value3, value4, value5;
;                   };
;
RetX_   proc    near ; struct int_values RetX()
        mov     &word ptr SS:0[&siup],71
        mov     &word ptr SS:4[&siup],72
        mov     &word ptr SS:8[&siup],73
        mov     &word ptr SS:12[&siup],74
        mov     &word ptr SS:16[&siup],75
        ret
RetX_   endp
_TEXT   ends
        end
.exam end
.np
When returning values on the stack, remember to use a segment override
to the stack segment (SS).
.endnote
.pc
The following is an example of a &cmpname program calling the above
assembly language subprograms.
.keep 12
.millust begin
#include <stdio.h>

struct int_values {
    int value1;
    int value2;
    int value3;
    int value4;
    int value5;
};

.millust break
extern  char              Ret1(void);
extern  short int         Ret2(void);
extern  long int          Ret4(void);
extern  double            Ret8(void);
extern  struct int_values RetX(void);

.millust break
void main()
{
    struct int_values x;

    printf( "Ret1 = %c\n", Ret1() );
    printf( "Ret2 = %d\n", Ret2() );
    printf( "Ret4 = %ld\n", Ret4() );
    printf( "Ret8 = %f\n", Ret8() );
    x = RetX();
    printf( "RetX1 = %d\n", x.value1 );
    printf( "RetX2 = %d\n", x.value2 );
    printf( "RetX3 = %d\n", x.value3 );
    printf( "RetX4 = %d\n", x.value4 );
    printf( "RetX5 = %d\n", x.value5 );
}
.millust end
.pc
The above function should be compiled for a small code model (use the
.if '&machine' eq '8086' .do begin
"ms" or "mc" compiler option).
.do end
.el .do begin
"mf", "ms" or "mc" compiler option).
.do end
.if '&machine' eq '80386' .do begin
.remark
.ix 'stack-based calling convention' 'returning values from functions'
.ix 'options' 'fpc'
Returning values from functions in the stack-based calling convention
is the same as returning values from functions in the register-based
calling convention when using the "fpc" option.
.eremark
.do end
.endlevel
.*
.section Calling Conventions for 80x87-based Applications
.*
.np
.ix 'passing arguments' 'in 80x87-based applications'
When a source file is compiled by &cmpname with one of the
"fpi" or "fpi87"
options, all floating-point arguments are passed on the 80x86 stack.
The rules for passing arguments are as follows.
.autonote
.note
If the argument is not floating-point, use the procedure described
earlier in this chapter.
.note
If the argument is floating-point, it is assigned a position on the
80x86 stack.
.endnote
.if '&machine' eq '80386' .do begin
.remark
.ix 'stack-based calling convention' '80x87 considerations'
When compiling using the "fpi" or "fpi87" options, the method used for
passing floating-point arguments in the stack-based calling convention
is identical to the method used in the register-based calling
convention.
However, when compiling using the "fpi" or "fpi87" options, the method
used for returning floating-point values in the stack-based calling
convention is different from the method used in the register-based
calling convention.
The register-based calling convention returns floating-point values in
ST(0), whereas the stack-based calling convention returns
floating-point values in EDX and EAX.
.eremark
.do end
.*
.beglevel
.*
.section Passing Values in 80x87-based Applications
.*
.np
.ix 'conventions' '80x87'
Consider the following example.
.cp 15
.exam begin
extern  void    myrtn(int,float,double,long int);

void main()
{
    float    x;
    double   y;
    int      i;
    long int j;

    x = 7.7;
    i = 7;
    y = 77.77
    j = 77;
    myrtn( i, x, y, j );
}
.exam end
.pc
.id myrtn
is an assembly language function that requires four arguments.
The first argument is of type "int" ( &intsize bytes),
the second argument is of type "float" (4 bytes),
the third argument is of type "double" (8 bytes)
and the fourth argument is of type "long int" (4 bytes).
.if '&machine' eq '8086' .do begin
These arguments will be passed to
.do end
.el .do begin
.np
When using the stack-based calling conventions, all of the arguments
will be passed on the stack.
When using the register-based calling conventions, the above arguments
will be passed to
.do end
.id myrtn
in the following way:
.autonote
.note
The first argument will be passed in register &axup leaving &bxup,
&cxup and &dxup as available registers for other arguments.
.note
The second argument will be passed on the 80x86 stack since it is a
floating-point argument.
.note
The third argument will also be passed on the 80x86 stack
since it is a floating-point argument.
.note
The fourth argument will be passed on the 80x86 stack since a previous
argument has been assigned a position on the 80x86 stack.
.endnote
.pc
Remember, arguments are pushed on the stack from right to
left.
That is, the rightmost argument is pushed first.
.np
Any assembly language function must obey the following rule.
.autonote
.note
All arguments passed on the stack must be removed by the called function.
.endnote
.np
The following is a sample assembly language function which
implements
.id myrtn.
.cp 13
.exam begin
        .8087
_TEXT   segment byte public 'CODE'
        assume  CS:_TEXT
        public  myrtn_
myrtn_  proc    near
;
; body of function
;
        ret 16           ; return and pop arguments
myrtn_  endp
_TEXT   ends
        end
.exam end
.autonote Notes:
.note
Function names must be followed by an underscore.
.note
All used 80x86 registers must be saved on entry and restored on exit
except those used to pass arguments and return values.
.ix 'options' 'r'
Note that segment registers only have to saved and restored if you are
compiling your application with the "r" option.
In this example, &axup does not have to be saved as it was
used to pass the first argument.
Floating-point registers can be modified without saving their contents.
.note
The direction flag must be clear before returning to the caller.
.note
This function has been written for a small code model.
Any segment containing executable code must belong to the class "CODE"
and the segment "_TEXT".
On entry, CS contains the segment address of the segment "_TEXT".
The above restrictions do not apply in a big code memory model.
.note
When writing assembly language functions for a small code model, you
must declare them as "near".
If you wish to write assembly language functions for a big code model,
you must declare them as "far".
.endnote
.*
.section Returning Values in 80x87-based Applications
.*
.np
.ix 'conventions' '80x87'
.if '&machine' eq '8086' .do begin
Floating-point values are returned in ST(0) when using the "fpi" or
"fpi87" options.
.do end
.el .do begin
When using the stack-based calling conventions with "fpi" or "fpi87",
floating-point values are returned in registers.
Single precision values are returned in EAX, and double precision
values are returned in EDX:EAX.
.np
When using the register-based calling conventions with "fpi" or
"fpi87", floating-point values are returned in ST(0).
.do end
All other values are returned in the manner described earlier in this
chapter.
.endlevel
.*
.if &e'&dohelp eq 1 .do begin
.   .if '&machine' eq '8086' .do begin
.   .   .helppref
.   .do end
.   .el .do begin
.   .   .helppref
.   .do end
.do end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -