Listing 2.  PUSH_POP Far Version
    ...

   null_word         DW    0  ; stack unloading zone
   far_address       DD    0  ; temporary far call address

    ...

push_pop  proc  far

   pushf                   ; push flags
   push  ax                ;  and all of the general
   push  bx                ;  purpose
   push  cx                ;  registers prior to 
   push  dx                ;  the execution of the
   push  bp                ;  code in
   push  di                ;  the
   push  si                ;  calling
   push  ds                ;  routine
   push  es                ;  

   push  ax                         ; double push ax and bp
   push  bp                         ;  then
   pushf                            ;  save flags too
   mov   bp,sp                      ; set up [BP] addressing
   add   bp,26                      ; point to return offset
   mov   ax,[bp]                    ; get into register then
   mov   word ptr far_address,ax    ;  into DD address
   add   bp,2                       ; point to RET segment
   mov   ax,[bp]                    ; get into register then
   mov   word ptr far_address+2,ax  ;  into DD address
   popf                             ; restore flags
   pop   bp                         ; restore any parameters
   pop   ax                         ; passed in ax or bp

   call  far_address       ; recursively call original proc

   pop   es                ; restore
   pop   ds                ; all
   pop   si                ; general
   pop   di                ; use
   pop   bp                ; register
   pop   dx                ; values for
   pop   cx                ; return to
   pop   bx                ; point just following
   pop   ax                ; original call
   popf                    ; restore flag values

   pop   null_word         ; adjust stack to point
   pop   null_word         ;  to original return point

   ret

push_pop  endp

    ...


