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

📄 ccall.gml

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 GML
📖 第 1 页 / 共 4 页
字号:
.np
.if '&machine' eq '8086' .do begin
Register SP cannot be used as a base register to address the third
argument on the stack.
.do end
.ix 'addressing arguments'
Register &bpup is normally used to address arguments on the stack.
Upon entry to the function, register &bpup is set to point to the
stack but before doing so we must save its contents.
The following two instructions achieve this.
.millust begin
push    &bpup           ; save current value of &bpup
mov     &bpup,&spup      &fill; get access to arguments
.millust end
.np
After executing these instructions, the stack looks like this.
.if '&machine' eq '8086' .do begin
.millust begin
.us Small Code Model
.monoon
Offset
        +----------------+
  0     | saved BP       | <- BP and SP point here
        +----------------+
  2     | return address |
        +----------------+
  4     | argument #3    |
        |                |
        +----------------+
  8     |                |
.monooff
.millust end
.do end
.el .do begin
.millust begin
.us Small Code Model
.monoon
Offset
        +----------------+
  0     | saved EBP      | <- EBP and ESP point here
        +----------------+
  4     | return address |
        +----------------+
  8     | argument #3    |
        |                |
        +----------------+
 16     |                |
.monooff
.millust end
.do end
.if '&machine' eq '8086' .do begin
.millust begin
.us Big Code Model
.monoon
Offset
        +----------------+
  0     | saved BP       | <- BP and SP point here
        +----------------+
  2     | return address |
        |                |
        +----------------+
  6     | argument #3    |
        |                |
        +----------------+
 10     |                |
.monooff
.millust end
.do end
.el .do begin
.millust begin
.us Big Code Model
.monoon
Offset
        +----------------+
  0     | saved EBP      | <- EBP and ESP point here
        +----------------+
  4     | return address |
        |                |
        +----------------+
 12     | argument #3    |
        |                |
        +----------------+
 20     |                |
.monooff
.millust end
.do end
.pc
As the above diagrams show, the third argument is at offset &s_o2 from
register &bpup in a small code model and offset &b_o2 in a big code model.
.np
Upon exit from
.id myrtn,
we must restore the value of &bpup..
The following two instructions achieve this.
.millust begin
mov     &spup,&bpup      &fill; restore stack pointer
pop     &bpup           ; restore &bpup
.millust end
.pc
The following is a sample assembly language function which
implements
.id myrtn.
.if '&machine' eq '8086' .do begin
:set symbol="argsize" value="4".
.do end
.el .do begin
:set symbol="argsize" value="8".
.do end
.tb set $
.tb 20 28 38
.millust begin
.us Small Memory Model (small code, small data)
.monoon
DGROUP  $group  $_DATA, _BSS
_TEXT   $segment byte public 'CODE'
        $assume $CS:_TEXT
        $assume $DS:DGROUP
        $public $myrtn_
myrtn_  $proc   $near
        $push   $&bpup        $; save &bpup
        $mov    $&bpup,&spup  $; get access to arguments
;
; body of function
;
        $mov    $&spup,&bpup  $; restore &spup
        $pop    $&bpup        $; restore &bpup
        $ret    $&argsize     $; return and pop last arg
myrtn_  $endp
_TEXT   $ends
:cmt. ;
:cmt. ; Data Definitions (initialized).
:cmt. ;
:cmt.         $public $_GblData
:cmt. _DATA   $segment byte public 'DATA'
:cmt. LocData $dd     $0
:cmt. _GblData $dd    $0
:cmt. _DATA   $ends
:cmt. ;
:cmt. ; Data Definitions (uninitialized)
:cmt. ;
:cmt. _BSS    $segment byte public 'BSS'
:cmt. XData   $dd     $?
:cmt. _BSS    $ends
:cmt.         $end
.monooff
.millust end
.millust begin
.us Large Memory Model (big code, big data)
.monoon
DGROUP  $group $_DATA, _BSS
MYRTN_TEXT segment byte public 'CODE'
        $assume $CS:MYRTN_TEXT
        $public $myrtn_
myrtn_  $proc   $far
        $push   $&bpup        $; save &bpup
        $mov    $&bpup,&spup  $; get access to arguments
;
; body of function
;
        $mov    $&spup,&bpup  $; restore &spup
        $pop    $&bpup        $; restore &bpup
        $ret    $&argsize     $; return and pop last arg
myrtn_  $endp
MYRTN_TEXT ends
:cmt. ;
:cmt. ; Data Definitions
:cmt. ;
:cmt.         $public $_GblData
:cmt. _DATA   $segment byte public 'DATA'
:cmt. LocData $dd     $0
:cmt. _GblData $dd    $0
:cmt. _DATA   $ends
:cmt. ;
:cmt. ; Data Definitions (uninitialized)
:cmt. ;
:cmt. _BSS    $segment byte public 'BSS'
:cmt. XData   $dd     $?
:cmt. _BSS    $ends
:cmt.         $end
.monooff
.millust end
.tb set
.tb
.autonote Notes:
.note
Global function names must be followed with an underscore.
Global variable names must be preceded with 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.
.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
If any of the arguments was pushed onto the stack,
the called routine must pop those arguments off the stack in the "ret"
instruction.
.endnote
.*
.if '&machine' eq '80386' .do begin
.section Using Stack-Based Calling Conventions
.*
.np
.ix 'stack-based calling convention'
Let us now consider the example in the previous section except this time
we will use the stack-based calling convention.
The most significant difference between the stack-based calling convention
and the register-based calling convention is the way the arguments are
passed.
When using the stack-based calling conventions, no registers are used to
pass arguments.
Instead, all arguments are passed on the stack.
.np
Let us look at the stack upon entry to
.id myrtn.
.millust begin
.us Small Code Model
.monoon
Offset
        +----------------+
  0     | return address | <- ESP points here
        +----------------+
  4     | argument #1    |
        |                |
        +----------------+
 12     | argument #2    |
        |                |
        +----------------+
 16     | argument #3    |
        |                |
        +----------------+
 24     |                |
.monooff
.millust end
.millust begin
.us Big Code Model
.monoon
Offset
        +----------------+
  0     | return address | <- ESP points here
        |                |
        +----------------+
  8     | argument #1    |
        |                |
        +----------------+
 16     | argument #2    |
        |                |
        +----------------+
 20     | argument #3    |
        |                |
        +----------------+
 28     |                |
.monooff
.millust 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
: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=" ".
.np
.ix 'addressing arguments'
Register &bpup is normally used to address arguments on the stack.
Upon entry to the function, register &bpup is set to point to the stack
but before doing so we must save its contents.
The following two instructions achieve this.
.millust begin
push    &bpup           ; save current value of &bpup
mov     &bpup,&spup      &fill; get access to arguments
.millust end
.np
After executing these instructions, the stack looks like this.
.millust begin
.us Small Code Model
.monoon
Offset
        +----------------+
  0     | saved EBP      | <- EBP and ESP point here
        +----------------+
  4     | return address |
        +----------------+
  8     | argument #1    |
        |                |
        +----------------+
 16     | argument #2    |
        |                |
        +----------------+
 20     | argument #3    |
        |                |
        +----------------+
 28     |                |
.monooff
.millust end
.millust begin
.us Big Code Model
.monoon
Offset
        +----------------+
  0     | saved EBP      | <- EBP and ESP point here
        +----------------+
  4     | return address |
        |                |
        +----------------+
 12     | argument #1    |
        |                |
        +----------------+
 20     | argument #2    |
        |                |
        +----------------+
 24     | argument #3    |
        |                |
        +----------------+
 32     |                |
.monooff
.millust end
.pc
As the above diagrams show, the argument are all on the stack and are
referenced by specifying an offset from register &bpup..
.np
Upon exit from
.id myrtn,
we must restore the value of &bpup..
The following two instructions achieve this.
.millust begin
mov     &spup,&bpup      &fill; restore stack pointer
pop     &bpup           ; restore &bpup
.millust end
.pc
The following is a sample assembly language function which
implements
.id myrtn.
.tb set $
.tb 20 28 38
.millust begin
.us Small Memory Model (small code, small data)
.monoon
DGROUP  $group  $_DATA, _BSS
_TEXT   $segment byte public 'CODE'
        $assume $CS:_TEXT
        $assume $DS:DGROUP
        $public $myrtn
myrtn   $proc   $near
        $push   $&bpup        $; save &bpup
        $mov    $&bpup,&spup  $; get access to arguments
;
; body of function
;
        $mov    $&spup,&bpup  $; restore &spup
        $pop    $&bpup        $; restore &bpup
        $ret    $             $; return
myrtn   $endp
_TEXT   $ends
:cmt. ;
:cmt. ; Data Definitions (initialized).
:cmt. ;
:cmt.        $public $_GblData
:cmt. _DATA  $segment byte public 'DATA'
:cmt. LocData  $dd   $0
:cmt. _GblData $dd   $0
:cmt. _DATA  $ends
:cmt. ;
:cmt. ; Data Definitions (uninitialized)
:cmt. ;
:cmt. _BSS   $segment byte public 'BSS'
:cmt. XData  $dd     $?
:cmt. _BSS   $ends
:cmt.        $end
.monooff
.millust end
.millust begin
.us Large Memory Model (big code, big data)
.monoon
DGROUP $group   $_DATA, _BSS
MYRTN_TEXT segment byte public 'CODE'
       $assume  $CS:MYRTN_TEXT
       $public  $myrtn
myrtn  $proc    $far
       $push    $&bpup       $; save &bpup
       $mov     $&bpup,&spup $; get access to arguments
;
; body of function
;
       $mov     $&spup,&bpup  $; restore &spup
       $pop     $&bpup        $; restore &bpup
       $ret     $             $; return
myrtn  $endp
MYRTN_TEXT ends
:cmt. ;
:cmt. ; Data Definitions
:cmt. ;
:cmt.        $public  $_GblData
:cmt. _DATA  $segment byte public 'DATA'
:cmt. LocData $dd     $0
:cmt. _GblData $dd    $0
:cmt. _DATA  $ends
:cmt. ;
:cmt. ; Data Definitions (uninitialized)
:cmt. ;
:cmt. _BSS   $segment byte public 'BSS'
:cmt. XData  $dd      $?
:cmt. _BSS   $ends
:cmt.        $end
.monooff
.millust end
.tb set
.tb
.autonote Notes:
.note
Global function names must not be followed with an underscore as was the
case with the register-based calling convention.
Global variable names must not be preceded with an underscore as was the
case with the register-based calling convention.

⌨️ 快捷键说明

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