Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Peter Norton Programmer's Guide - Norton Guide http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]

  We'll start our discussion of specific high-level languages with the C
  language. In previous chapters we've already shown you several examples of
  the C subroutine interface. Now we'll show how to adapt that interface to
  different parameter-passing methods and memory models. Although the
  examples we'll give you here pertain specifically to the Microsoft C
  compiler, you'll find that essentially the same subroutine interface
  design can be used not only in other vendors' compiler implementations,
  but in other programming languages as well.

  The C subroutines presented in previous chapters used a small memory model
  and the pass-by-value convention. The subroutine on the following page
  which computes the absolute value of an integer, uses the same
  conventions.

  The subroutine uses a near call-return sequence because the program uses a
  small memory model with all executable code in the same segment. The
  parameter value is passed to the subroutine on the stack and accessed
  through BP in the usual way. The parameter value is found at [BP + 4]
  because the first 4 bytes of the stack are used by the calling program's
  return address (2 bytes) and the saved value of BP (2 bytes).

  _TEXT           SEGMENT byte public 'CODE'
                  ASSUME  cs:_TEXT

                  PUBLIC  _AbsValue
  _AbsValue       PROC    near            ; call with near CALL

                  push    bp
                  mov     bp,sp

                  mov     ax,[bp+4]       ; AX = value of 1st parameter

                  cwd
                  xor     ax,dx
                  sub     ax,dx           ; leave result in AX

                  pop     bp
                  ret                     ; near RETurn

  _AbsValue       ENDP

  _TEXT           ENDS

  The subroutine uses register AX to return its result to the calling
  program. If the return value had been a 4-byte value, the register pair
  DX:AX would have been used, with the high-order word of the value in DX.

  If this subroutine had used more than one parameter, the second and
  subsequent parameters would have been found at higher addresses on the
  stack. For example, the second parameter would have been located at
  [BP + 6]. (See the Weekday() subroutine in Chapter 16 for an example.) In
  effect, the C compiler pushes parameters on the stack in reverse of their
  declared order. Because of this, a subroutine always knows where to find
  the first parameter on the stack. A C function like printf() can use a
  variable number of parameters if the first parameter specifies the actual
  number of parameters.

  When it returns, the subroutine leaves the value of the parameter on the
  stack. In C, the calling program must clean up the stack after a
  subroutine call. For example, consider the way a C compiler generates
  executable code for a simple C statement that calls AbsValue():

  x = AbsValue( y );      /* x and y are integers */

  The executable code generated by the C compiler for this statement looks
  something like this:

  push Y                  ; push the value at address Y
  call _AbsValue          ; call the subroutine (near call)
  add  sp,2               ; discard the value from the stack
  mov  X,ax               ; store the returned value at address X

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson