;       Static Name Aliases
;
        TITLE   strnmov
;       NAME    strnmov.C

;   strnmov(dst, src, n) moves up to n characters of  src  to  dst.   It
;   always  moves  exactly n characters to dst; if src is shorter than n
;   characters dst will be extended on the right with NULs, while if src
;   is longer than n characters dst will be a truncated version of src.
;   Unlink the UNIX version, dst will have a NUL appended.
;
;   The result is a pointer to the first NUL in dst.

        .287
_TEXT   SEGMENT  BYTE PUBLIC 'CODE'
_TEXT   ENDS
_DATA   SEGMENT  WORD PUBLIC 'DATA'
_DATA   ENDS
CONST   SEGMENT  WORD PUBLIC 'CONST'
CONST   ENDS
_BSS    SEGMENT  WORD PUBLIC 'BSS'
_BSS    ENDS
DGROUP  GROUP   CONST,  _BSS,   _DATA
        ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
EXTRN   __chkstk:NEAR
_TEXT      SEGMENT
        PUBLIC  _strnmov
_strnmov        PROC NEAR
        push    bp
        mov     bp,sp
        push    di
        push    si
        mov     di,[bp+4]       ;dst
        mov     si,[bp+6]       ;src

;       dst = 4
;       register di = dst
;       src = 6
;       register si = src
;       n = 8

        mov     cx,[bp+8]
        jcxz    cleanup
$loop:
        movsb
        cmp     byte ptr [si - 1],0
        je      pad
        loop    $loop
        jmp     short cleanup
pad:
        xor     al,al
        mov     si,di
        repnz   stosb
        mov     di,si
        dec     di
cleanup:
        cmp     byte ptr [di],0
        je      $out
        xor     al,al
        mov     [di],al
$out:
        xchg    ax,di
        pop     si
        pop     di
        mov     sp,bp
        pop     bp
        ret

_strnmov        ENDP
_TEXT   ENDS
END
