Rational Developer for System z
PL/I for Windows, Version 7.6, Programming Guide

Example using SYSTEM linkage

The following example is included only for purposes of illustration and clarity and has not been optimized. The example assumes that you are familiar with programming in assembler. In the example, the stack grows toward the bottom of the page, and ESP always points to the top of the stack.

The following example shows the code sequences and a picture of the stack for a call to the function FUNC3 which has two local variables, x and y (both fixed bin(31)). For the call

 dcl func3 entry( fixed bin(31),
                  fixed bin(31),
                  fixed bin(31) )
     returns( fixed bin(31) )
     options( byvalue nodescriptor linkage(system) );

  m = func3(a,b,c);

the stack for the call to FUNC3 would look like this:

                                     Stack

                           .------------------------.       Higher Memory
                           |           c            |
                           '------------------------'
                           |           b            |
                           '------------------------'
                           |           a            |
                           '------------------------'
                           |     caller's EIP       |
                           '------------------------'
                           |     caller's EBP       |
           EBP  ------>    '------------------------'
                           |           x            |
                           '------------------------'
                           |           y            |
                           '------------------------'   <-.
                           |       Saved EDI        |     |
                           '------------------------'     | These would only be
                           |       Saved ESI        |     | be pushed if they
                           '------------------------'     | were used in this
                           |       Saved EBX        |     | function.
           ESP  ------>    '------------------------'   <-'
                                                            Lower Memory

The instructions used to build this activation record on the stack look like this on the calling side:

      PUSH    c
      PUSH    b
      PUSH    a
      MOV     AL, 3H
      CALL    func3
          .
          .
      ADD     ESP, 12    ; Cleaning up the parameters
          .
          .
      MOV     m, EAX
          .
          .

For the callee, the code looks like this:

func3 PROC
      PUSH    EBP
      MOV     EBP, ESP           ;  Allocating 8 bytes of storage
      SUB     ESP, 8             ;   for two local variables.
      PUSH    EDI                ; These would only be
      PUSH    ESI                ;  pushed if they were used
      PUSH    EBX                ;  in this function.
      .
      .
      MOV     EAX, [EBP - 8]    ; Load y into EAX
      MOV     EBX, [EBP + 12]   ; Load b into EBX
      .
      .
      XOR     EAX, EAX           ; Zero the return value
      POP     EBX                ; Restore the saved registers
      POP     ESI
      POP     EDI
      LEAVE                      ; Equivalent to  MOV   ESP, EBP
                                 ;                POP   EBP
      RET
func3 ENDP

The saved register set is EBX, ESI, and EDI. The other registers (EAX, ECX, and EDX) can have their contents changed by a called routine.

Under some circumstances, the compiler does not use EBP to access automatic and parameter values, thus increasing the application's efficiency. Whether it is used or not, EBP does not change across the call.

When passing aggregates by value, the compiler generates code to copy the aggregate on to the 80386 stack. If the size of the aggregate is larger than an 80386 page size (4K), the compiler generates code to copy the aggregate backward (that is, the last byte in the aggregate is the first to be copied).

Aggregates are not returned on the stack. The caller pushes the address where the returned aggregate is to be placed as a lexically first hidden parameter. A function that returns an aggregate must be aware that all parameters are 4 bytes farther away from EBP than they would be if no aggregate return were involved. The address of the returned aggregate is returned in EAX.


Terms of use | Feedback

This information center is powered by Eclipse technology. (http://www.eclipse.org)