_file_length:
; Public domain code by Rowan Crowe (3:635/727.1@fidonet)
;                       rowan@jelly.freeway.DIALix.oz.au
; From the MoonRock compiler ASM library
; BX contains file handle
; returns: DX:AX = file size
    push    bp
    mov     bp,sp
    sub     sp,4
    push    cx
    xor     cx,cx
    xor     dx,dx
    mov     ax,4201h    ; find current file position
    int     21h
    mov     word ptr [bp-2],ax
    mov     word ptr [bp-4],dx
    xor     cx,cx
    xor     dx,dx       ; seek 0 bytes
    mov     ax,4202h    ; origin of move is end of file
    int     21h         ; CX:DX now contains size of file
    push    ax
    push    dx
    mov     cx,word ptr [bp-4]
    mov     dx,word ptr [bp-2]
    mov     ax,4200h    ; restore original file position
    int     21h
    pop     dx
    pop     ax
    pop     cx
    mov     sp,bp
    pop     bp
    ret

The stack-based local variables could probably be replaced with SI and DI to
keep it all in registers. This routine may be overkill because it restores the
original file pointer; if you just need to know the length, and changing the
file pointer does not matter, then use:

; BX contains file handle
    mov ax,4202h
    xor cx,cx
    xor dx,dx
    int 21h
; CX:DX contains size of file, file pointer points to end of file

