📄 ccall.gml
字号:
.if '&machine' eq '8086' .do begin
:set symbol="calref" value="cal86".
:set symbol="calttl" value="16-bit Assembly Language Considerations".
:set symbol="machint" value="short int".
:set symbol="intsize" value="2".
:set symbol="maxint" value="32767".
:set symbol="umaxint" value="65535".
:set symbol="minint" value="-32768".
:set symbol="ax" value="ax".
:set symbol="axup" value="AX".
:set symbol="bx" value="bx".
:set symbol="bxup" value="BX".
:set symbol="cx" value="cx".
:set symbol="cxup" value="CX".
:set symbol="dx" value="dx".
:set symbol="dxup" value="DX".
:set symbol="di" value="di".
:set symbol="diup" value="DI".
:set symbol="si" value="si".
:set symbol="siup" value="SI".
:set symbol="bp" value="bp".
:set symbol="bpup" value="BP".
:set symbol="sp" value="sp".
:set symbol="spup" value="SP".
:set symbol="reg4" value="DX AX".
:set symbol="reg8" value="AX BX CX DX".
:set symbol="arg_2_regs" value="long int".
:set symbol="typ_2_regs" value="long int".
:set symbol="nearsize" value="1 word (16 bits)".
:set symbol="farsize" value="2 words (32 bits)".
:set symbol="bitmode" value="16-bit mode".
:set symbol="nptrsz" value="2".
:set symbol="nargsz" value="2".
:set symbol="fptrsz" value="4".
:set symbol="fargsz" value="4".
.do end
.el .do begin
:set symbol="calref" value="cal386".
:set symbol="calttl" value="32-bit Assembly Language Considerations".
:set symbol="machint" value="long int".
:set symbol="intsize" value="4".
:set symbol="maxint" value="2147483647".
:set symbol="umaxint" value="4294967295".
:set symbol="minint" value="-2147483648".
:set symbol="ax" value="eax".
:set symbol="axup" value="EAX".
:set symbol="bx" value="ebx".
:set symbol="bxup" value="EBX".
:set symbol="cx" value="ecx".
:set symbol="cxup" value="ECX".
:set symbol="dx" value="edx".
:set symbol="dxup" value="EDX".
:set symbol="di" value="edi".
:set symbol="diup" value="EDI".
:set symbol="si" value="esi".
:set symbol="siup" value="ESI".
:set symbol="bp" value="ebp".
:set symbol="bpup" value="EBP".
:set symbol="sp" value="esp".
:set symbol="spup" value="ESP".
:set symbol="reg4" value="EAX".
:set symbol="reg8" value="EDX EAX".
:set symbol="arg_2_regs" value="double ".
:set symbol="typ_2_regs" value="double".
:set symbol="nearsize" value="1 double word (32 bits)".
:set symbol="farsize" value="2 double words (64 bits)".
:set symbol="bitmode" value="32-bit mode".
:set symbol="nptrsz" value="4".
:set symbol="nargsz" value="4".
:set symbol="fptrsz" value="6".
:set symbol="fargsz" value="8".
.do end
.*
.chap *refid=&calref. &calttl.
.*
.ix 'calling conventions'
.*
.if &e'&dohelp eq 0 .do begin
.section Introduction
.do end
.el .do begin
. .if '&machine' eq '8086' .do begin
. . .helppref 16-bit:
. .do end
. .el .do begin
. . .helppref 32-bit:
. .do end
.do end
.*
.np
This chapter will deal with the following topics.
.autonote
.note
The data representation of the basic types supported by &cmpname..
.note
The memory layout of a &cmpname program.
.note
The method for passing arguments and returning values.
.note
The two methods for passing floating-point arguments and returning
floating-point values.
.np
One method is used when one of the &cmpname
"fpi" or "fpi87"
options is specified for the generation of in-line 80x87 instructions.
When the "fpi" option is specified, an 80x87 emulator is included from
a math library if the application includes floating-point operations.
When the "fpi87"
option is used exclusively, the 80x87 emulator will not be included.
.np
The other method is used when the &cmpname "fpc" option is specified.
In this case, the compiler generates calls to floating-point support
routines in the alternate math libraries.
.endnote
.pc
An understanding of the Intel 80x86 architecture is assumed.
.*
.section Data Representation
.*
.np
.ix 'data types'
.ix 'data representation'
This section describes the internal or machine representation of the
basic types supported by &cmpname..
.*
.beglevel
.*
.section Type "char"
.*
.np
.ix 'types' 'char'
.ix 'char type'
An item of type "char" occupies 1 byte of storage.
Its value is in the following range.
.millust begin
0 <= n <= 255
.millust end
.pc
Note that "char" is, by default, unsigned.
The &cmpname compiler option "j" can be used to change the default
from unsigned to signed.
If "char" is signed, an item of type "char" is in the following range.
.millust begin
-128 <= n <= 127
.millust end
.pc
You can force an item of type "char" to be unsigned or signed regardless
of the default by defining them to be of type "unsigned char" or
"signed char" respectively.
.*
.section Type "short int"
.*
.np
.ix 'types' 'short int'
.ix 'short int type'
An item of type "short int" occupies 2 bytes of storage.
Its value is in the following range.
.millust begin
-32768 <= n <= 32767
.millust end
.pc
Note that "short int" is signed and hence "short int" and
"signed short int" are equivalent.
If an item of type "short int" is to be unsigned, it must be defined as
"unsigned short int".
In this case, its value is in the following range.
.millust begin
0 <= n <= 65535
.millust end
.*
.*
.section Type "long int"
.*
.np
.ix 'types' 'long int'
.ix 'long int type'
An item of type "long int" occupies 4 bytes of storage.
Its value is in the following range.
.millust begin
-2147483648 <= n <= 2147483647
.millust end
.pc
Note that "long int" is signed and hence "long int" and
"signed long int" are equivalent.
If an item of type "long int" is to be unsigned, it must be defined as
"unsigned long int".
In this case, its value is in the following range.
.millust begin
0 <= n <= 4294967295
.millust end
.*
.section Type "int"
.*
.np
.ix 'types' 'int'
.ix 'int type'
An item of type "int" occupies &intsize bytes of storage.
Its value is in the following range.
.millust begin
&minint <= n <= &maxint
.millust end
.pc
Note that "int" is signed and hence "int" and "signed int" are
equivalent.
If an item of type "int" is to be unsigned, it must be defined as
"unsigned int".
In this case its value is in the following range.
.millust begin
0 <= n <= &umaxint
.millust end
.np
If you are generating code that executes in &bitmode, "&machint" and
"int" are equivalent, "unsigned &machint" and "unsigned int" are
equivalent, and "signed &machint" and "signed int" are equivalent.
This may not be the case in other environments where "int" and
.if '&machine' eq '8086' .do begin
"long int" are 4 bytes.
.do end
.el .do begin
"short int" are 2 bytes.
.do end
.*
.section Type "float"
.*
.np
.ix 'types' 'float'
.ix 'float type'
A datum of type "float" is an approximate representation of a real
number.
Each datum of type "float" occupies 4 bytes.
If
.id m
is the magnitude of
.id x
(an item of type "float") then
.id x
can be approximated if
.millust begin
.if &e'&dohelp eq 0 .do begin
2&S'-126. <= m < 2&S'128.
.do end
.el .do begin
-126 128
2 <= m < 2
.do end
.millust end
.pc
or in more approximate terms if
.millust begin
1.175494e-38 <= m <= 3.402823e38
.millust end
.np
Data of type "float" are represented internally as follows.
Note that bytes are stored in memory with the least significant byte
first and the most significant byte last.
.millust begin
+---+---------+---------------------+
| S | Biased | Significand |
| | Exponent| |
+---+---------+---------------------+
31 30-23 22-0
.millust end
.begnote
.notehd1 Notes
.notehd2 ~b
.note S
S = Sign bit (0=positive, 1=negative)
.note Exponent
.if &e'&dohelp eq 0 .do begin
.sr n1=2&S'-126.
.sr n2=2&S'0.
.sr n3=2&S'127.
.do end
.el .do begin
.sr n1=2**-126
.sr n2=2**0
.sr n3=2**127
.do end
The exponent bias is 127 (i.e., exponent value 1 represents &n1.;
exponent value 127 represents &n2.; exponent value 254 represents
&n3.; etc.).
The exponent field is 8 bits long.
.note Significand
The leading bit of the significand is always 1, hence it is
not stored in the significand field. Thus the significand is
always "normalized".
The significand field is 23 bits long.
.note Zero
A real zero quantity occurs when the sign bit, exponent, and
significand are all zero.
.note Infinity
When the exponent field is all 1 bits and the significand field is
all zero bits then the quantity represents positive or negative
infinity, depending on the sign bit.
.note Not Numbers
When the exponent field is all 1 bits and the significand field is
non-zero then the quantity is a special value called a NAN
(Not-A-Number).
.np
When the exponent field is all 0 bits and the significand field is
non-zero then the quantity is a special value called a "denormal"
or nonnormal number.
.endnote
.*
.section Type "double"
.*
.np
.ix 'types' 'double'
.ix 'double type'
A datum of type "double" is an approximate representation of
a real number.
The precision of a datum of type "double" is greater than or equal to
one of type "float".
Each datum of type "double" occupies 8 bytes.
If
.id m
is the magnitude of
.id x
(an item of type "double") then
.id x
can be approximated if
.millust begin
.if &e'&dohelp eq 0 .do begin
2&S'-1022. <= m < 2&S'1024.
.do end
.el .do begin
-1022 1024
2 <= m < 2
.do end
.millust end
.pc
or in more approximate terms if
.millust begin
2.2250738585072e-308 <= m <= 1.79769313486232e308
.millust end
.np
Data of type "double" are represented internally as follows.
Note that bytes are stored in memory with the least significant byte
first and the most significant byte last.
.millust begin
+---+---------+--------------------------------------+
| S | Biased | Significand |
| | Exponent| |
+---+---------+--------------------------------------+
63 62-52 51-0
.millust end
.begnote
.notehd1 Notes:
.notehd2 ~b
.note S
S = Sign bit (0=positive, 1=negative)
.note Exponent
.if &e'&dohelp eq 0 .do begin
.sr n1=2&S'-1022.
.sr n2=2&S'0.
.sr n3=2&S'1023.
.do end
.el .do begin
.sr n1=2**-1022
.sr n2=2**0
.sr n3=2**1023
.do end
The exponent bias is 1023 (i.e., exponent value 1 represents &n1.;
exponent value 1023 represents &n2.; exponent value 2046 represents
&n3.; etc.).
The exponent field is 11 bits long.
.note Significand
The leading bit of the significand is always 1, hence it is
not stored in the significand field. Thus the significand is
always "normalized".
The significand field is 52 bits long.
.note Zero
A double precision zero quantity occurs when the sign bit,
exponent, and significand are all zero.
.note Infinity
When the exponent field is all 1 bits and the significand field is
all zero bits then the quantity represents positive or negative
infinity, depending on the sign bit.
.note Not Numbers
When the exponent field is all 1 bits and the significand field is
non-zero then the quantity is a special value called a NAN
(Not-A-Number).
.np
When the exponent field is all 0 bits and the significand field is
non-zero then the quantity is a special value called a "denormal"
or nonnormal number.
.endnote
.endlevel
.*
.im wmemlay
.*
.section Calling Conventions for Non-80x87 Applications
.*
.np
.ix 'conventions' 'non-80x87'
The following sections describe the calling convention used when compiling
with the "fpc" compiler option.
.*
.beglevel
.*
.section Passing Arguments Using Register-Based Calling Conventions
.*
.np
.ix 'passing arguments'
How arguments are passed to a function with register-based calling
conventions is determined by the
size (in bytes) of the argument and where in the argument list the
argument appears.
Depending on the size, arguments are either passed in registers or on
the stack.
Arguments such as structures are almost always passed on the stack since
they are generally too large to fit in registers.
Since arguments are processed from left to right, the first few
arguments are likely to be passed in registers (if they can fit) and,
if the argument list contains many arguments,
the last few arguments are likely to be passed on the stack.
.np
.ix 'passing arguments' 'in registers'
The registers used to pass arguments to a function are &axup, &bxup, &cxup
and &dxup..
The following algorithm describes how arguments are passed to
functions.
.np
Initially, we have the following registers available for passing
arguments: &axup, &dxup, &bxup and &cxup..
Note that registers are selected from this list in the order they
appear.
That is, the first register selected is &axup and the last is &cxup..
For each argument
.us Ai,
starting with the left most argument, perform the following steps.
.autonote
.note
.ix 'passing arguments' '1 byte'
.ix 'passing arguments' '2 bytes'
If the size of
.us Ai
is 1 byte
.if '&machine' eq '80386' .do begin
or 2 bytes
.do end
.ct , convert it to &intsize bytes and proceed to the next step.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -