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

📄 ccall.gml

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 GML
📖 第 1 页 / 共 4 页
字号:
If
.us Ai
is of type "unsigned char"
.if '&machine' eq '80386' .do begin
or "unsigned short int"
.do end
.ct , it is converted to an "unsigned int".
If
.us Ai
is of type "signed char"
.if '&machine' eq '80386' .do begin
or "signed short int"
.do end
.ct , it is converted to a "signed int".
If
.us Ai
.if '&machine' eq '8086' .do begin
is a 1-byte structure,
.do end
.el .do begin
is a 1-byte or 2-byte structure,
.do end
the padding is determined by the compiler.
.note
If an argument has already been assigned a position on the stack,
.us Ai
will also be assigned a position on the stack.
Otherwise, proceed to the next step.
.note
.ix 'passing arguments' '&intsize bytes'
If the size of
.us Ai
is &intsize bytes, select a register from the list of available registers.
If a register is available,
.us Ai
is assigned that register.
The register is then removed from the list of available registers.
If no registers are available,
.us Ai
will be assigned a position on the stack.
.note
.ix 'passing arguments' 'far pointers'
.if '&machine' eq '8086' .do begin
If the size of
.us Ai
is 4 bytes,
.do end
.el .do begin
If the type of
.us Ai
is "far pointer",
.do end
select a register pair from the following list of combinations:
[&dxup &axup] or [&cxup &bxup].
The first available register pair is assigned to
.us Ai
and removed from the list of available pairs.
.if '&machine' eq '8086' .do begin
The high-order 16 bits of the argument are assigned to the first
register in the pair; the low-order 16 bits are assigned to the second
register in the pair.
.do end
.el .do begin
The segment value will actually be passed in register DX or CX and the
offset in register &axup or &bxup..
.do end
If none of the above register pairs is available,
.us Ai
will be assigned a position on the stack.
.if '&machine' eq '80386' .do begin
Note that 8 bytes will be pushed on the stack even though the size of
an item of type "far pointer" is 6 bytes.
.do end
.note
.ix 'passing arguments' '8 bytes'
.ix 'passing arguments' 'of type double'
If the type of
.us Ai
is "double" or "float" (in the absence of a function prototype),
.if '&machine' eq '8086' .do begin
select [AX BX CX DX] from the list of available registers.
All four registers are removed from the list of available registers.
The high-order 16 bits of the argument are assigned to the first
register and the low-order 16 bits are assigned to the fourth
register.
If any of the four registers is not available,
.do end
.el .do begin
select a register pair from the following list of combinations:
[EDX EAX] or [ECX EBX].
The first available register pair is assigned to
.us Ai
and removed from the list of available pairs.
The high-order 32 bits of the argument are assigned to the first
register in the pair; the low-order 32 bits are assigned to the second
register in the pair.
If none of the above register pairs is available,
.do end
.us Ai
will be assigned a position on the stack.
.note
All other arguments will be assigned a position on the stack.
.endnote
.autonote Notes:
.note
Arguments that are assigned a position on the stack are padded to a
multiple of &intsize bytes.
That is, if a 3-byte structure is assigned a position on the stack,
4 bytes will be pushed on the stack.
.note
Arguments that are assigned a position on the stack are pushed onto
the stack starting with the rightmost argument.
.endnote
.*
.section *refid=&calref.s Sizes of Predefined Types
.*
.np
The following table lists the predefined types, their size as returned
by the "sizeof" function, the size of an argument of that type and the
registers used to pass that argument if it was the only argument in
the argument list.
.ix 'size of' 'predefined types'
.ix 'predefined types' 'size of'
.ix 'size of' 'char'
.ix 'char' 'size of'
.ix 'size of' 'signed char'
.ix 'signed char' 'size of'
.ix 'size of' 'unsigned char'
.ix 'unsigned char' 'size of'
.ix 'size of' 'int'
.ix 'int' 'size of'
.ix 'size of' 'unsigned int'
.ix 'unsigned int' 'size of'
.ix 'size of' 'signed int'
.ix 'signed int' 'size of'
.ix 'size of' 'short int'
.ix 'short int' 'size of'
.ix 'size of' 'signed short int'
.ix 'signed short int' 'size of'
.ix 'size of' 'unsigned short int'
.ix 'unsigned short int' 'size of'
.ix 'size of' 'long int'
.ix 'long int' 'size of'
.ix 'size of' 'signed long int'
.ix 'signed long int' 'size of'
.ix 'size of' 'unsigned long int'
.ix 'unsigned long int' 'size of'
.ix 'size of' 'float'
.ix 'float' 'size of'
.ix 'size of' 'long float'
.ix 'long float' 'size of'
.ix 'size of' 'double'
.ix 'double' 'size of'
.ix 'size of' 'long double'
.ix 'long double' 'size of'
.ix 'size of' 'near pointer'
.ix 'near pointer' 'size of'
.ix 'size of' 'far pointer'
.ix 'far pointer' 'size of'
.np
.tb set ^
.tb &sysin.+5 &sysin.+15c &sysin.+23c &sysin.+31
.ul
^Basic Type^"sizeof"^Argument^Registers
.ul
^^^Size^Used
.tb &sysin.+5 &sysin.+15 &sysin.+23 &sysin.+31
^char^1^&intsize^[&axup]
^short int^2^&intsize^[&axup]
^int^&intsize.^&intsize^[&axup]
^long int^4^4^[&reg4]
^float^4^8^[&reg8]
^double^8^8^[&reg8]
^near pointer^&nptrsz.^&nargsz.^[&axup]
^far pointer^&fptrsz.^&fargsz.^[&dxup &axup]
.if '&machine' eq '8086' .do begin
^huge pointer^&fptrsz.^&fargsz.^[&dxup &axup]
.do end
.np
.us Note that the size of the argument listed in the table assumes
.us that no function prototypes are specified.
Function prototypes affect the way arguments are passed.
This will be discussed in the section entitled
"Effect of Function Prototypes on Arguments".
.autonote Notes:
.note
Provided no function prototypes exist, an argument will be converted
to a default type as described in the following table.
.begnote $compact $setptnt 15
.notehd1 Argument Type
.notehd2 Passed As
.note char
unsigned int
.note signed char
signed int
.note unsigned char
unsigned int
.if '&machine' eq '80386' .do begin
.note short
unsigned int
.note signed short
signed int
.note unsigned short
unsigned int
.do end
.note float
double
.endnote
.endnote
.*
.section Size of Enumerated Types
.*
.np
.ix 'size of' 'enumerated types'
.ix 'enumerated types' 'size of'
The integral type of an enumerated type is determined by the values of the
enumeration constants.
In strict ISO/ANSI C mode, all enumerated constants are of type
.id int.
In the extensions mode, the compiler will use the smallest integral
type possible (excluding
.id long
ints) that can represent all values of the enumerated type.
For instance, if the minimum and maximum values of the enumeration
constants are in the range &minus.128 and 127, the enumerated type will be
equivalent to a
.id signed char
(size = 1 byte).
All references to enumerated constants in the previous instance will have type
.id signed char.
An enumerated constant is always promoted to an
.id int
when passed as an argument.
.*
.section Effect of Function Prototypes on Arguments
.*
.np
.ix 'function prototypes' 'effect on arguments'
Function prototypes define the types of the formal parameters of a
function.
Their appearance affects the way in which arguments are passed.
An argument will be converted to the type of the corresponding formal
parameter in the function prototype.
Consider the following example.
.millust begin
void prototype( float x, int i );

void main()
{
  float x;
  int   i;

  x = 3.14;
  i = 314;
  prototype( x, i );
  rtn( x, i );
}
.millust end
.pc
The function prototype for
.id prototype
specifies that the first argument is to be passed as a "float"
and the second argument is to be passed as an "int".
This results in the first argument being passed in
.if '&machine' eq '8086' .do begin
registers DX and AX
.do end
.el .do begin
register EAX
.do end
and the second argument being passed in
.if '&machine' eq '8086' .do begin
register BX.
.do end
.el .do begin
register EDX.
.do end
.np
If no function prototype is given, as is the case for the function
.id rtn,
the first argument will be passed as a "double" and the
second argument would be passed as an "int".
This results in the first argument being passed in registers
.if '&machine' eq '8086' .do begin
AX, BX, CX and DX
.do end
.el .do begin
EDX and EAX
.do end
and the second argument being passed
.if '&machine' eq '8086' .do begin
on the stack.
.do end
.el .do begin
in register EBX.
.do end
.np
Note that even though both
.id prototype
and
.id rtn
were called with identical argument lists, the way in which the arguments
were passed was completely different simply because a function prototype
for
.id prototype
was specified.
Function prototyping is an excellent way to guarantee that arguments
will be passed as expected to your assembly language function.
.*
.section Interfacing to Assembly Language Functions
.*
.np
Consider the following example.
.exam begin
void main()
{
    &arg_2_regs x;
    int      i;
    &arg_2_regs y;

    x = 7;
    i = 77;
    y = 777;
    myrtn( x, i, y );
}
.exam end
.pc
.id myrtn
is an assembly language function that requires three arguments.
The first argument is of type "&typ_2_regs", the second argument is
of type "int" and the third argument is again of type
"&typ_2_regs".
Using the rules for register-based calling conventions,
these arguments will be passed to
.id myrtn
in the following way:
.autonote
.note
The first argument will be passed in registers &dxup and &axup leaving
&bxup and &cxup as available registers for other arguments.
.note
The second argument will be passed in register &bxup leaving &cxup as an
available register for other arguments.
.note
The third argument will not fit in register &cxup
.if '&machine' eq '8086' .do begin
(its size is 4 bytes)
.do end
.el .do begin
(its size is 8 bytes)
.do end
and hence will be pushed on the stack.
.endnote
.np
Let us look at the stack upon entry to
.id myrtn.
.if '&machine' eq '8086' .do begin
.millust begin
.us Small Code Model
.monoon
Offset
        +----------------+
  0     | return address | <- SP points here
        +----------------+
  2     | argument #3    |
        |                |
        +----------------+
  6     |                |
.monooff
.millust end
.do end
.el .do begin
.millust begin
.us Small Code Model
.monoon
Offset
        +----------------+
  0     | return address | <- ESP points here
        +----------------+
  4     | argument #3    |
        |                |
        +----------------+
 12     |                |
.monooff
.millust end
.do end
.if '&machine' eq '8086' .do begin
.millust begin
.us Big Code Model
.monoon
Offset
        +----------------+
  0     | return address | <- SP points here
        |                |
        +----------------+
  4     | argument #3    |
        |                |
        +----------------+
  8     |                |
.monooff
.millust end
.do end
.el .do begin
.millust begin
.us Big Code Model
.monoon
Offset
        +----------------+
  0     | return address | <- ESP points here
        |                |
        +----------------+
  8     | argument #3    |
        |                |
        +----------------+
 16     |                |
.monooff
.millust end
.do end
.autonote Notes:
.note
The return address is the top element on the stack.
In a small code model, the return address is
&nearsize; in a big code model, the return address is &farsize..
.endnote
.if '&machine' eq '8086' .do begin
:set symbol="s_o1" value=" 2".
:set symbol="s_o2" value=" 4".
:set symbol="s_o3" value=" 8".
:set symbol="b_o1" value=" 2".
:set symbol="b_o2" value=" 6".
:set symbol="b_o3" value="10".
:set symbol="fill" value="  ".
.do end
.el .do begin
:set symbol="s_o1" value=" 4".
:set symbol="s_o2" value=" 8".
:set symbol="s_o3" value="16".
:set symbol="b_o1" value=" 4".
:set symbol="b_o2" value="12".
:set symbol="b_o3" value="20".
:set symbol="fill" value=" ".
.do end

⌨️ 快捷键说明

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