c语言的memset到底是怎么实现的 是c标准库里面写的这样么

c语言的memset到底是怎么实现的 是c标准库里面写的这样么,第1张

memset在不同编译器里面实现方式是不一样的

不过 都要比你提供的几种要复杂 而且高效。

有些平台甚至是用汇编写的。

提供几种做参考:

void  __cdecl memset (
        void dst,
        int val,
        size_t count
        )
{
        void start = dst;
 
#if defined (_M_IA64) || defined (_M_AMD64)
 
        {
 
 
        __declspec(dllimport)
 
 
        void RtlFillMemory( void , size_t count, char );
 
        RtlFillMemory( dst, count, (char)val );
 
        }
 
#else  / defined (_M_IA64) || defined (_M_AMD64) /
        while (count--) {
                (char )dst = (char)val;
                dst = (char )dst + 1;
        }
#endif  / defined (_M_IA64) || defined (_M_AMD64) /
 
        return(start);
}#include <linux/typesh>
#include <asm/stringh>
 
#define OPSIZ (BITS_PER_LONG/8)
typedef unsigned long op_t;
 
void 
memset (void dstpp, int sc, size_t len)
{
  unsigned int c = sc;
  long int dstp = (long int) dstpp;
 
  if (len >= 8)
    {
      size_t xlen;
      op_t cccc;
 
      cccc = (unsigned char) c;
      cccc |= cccc << 8;
      cccc |= cccc << 16;
      if (OPSIZ > 4)
        / Do the shift in two steps to avoid warning if long has 32 bits  /
        cccc |= (cccc << 16) << 16;
 
      / There are at least some bytes to set
         No need to test for LEN == 0 in this alignment loop  /
      while (dstp % OPSIZ != 0)
        {
          ((unsigned char ) dstp)[0] = c;
          dstp += 1;
          len -= 1;
        }
 
      / Write 8 `op_t' per iteration until less than 8 `op_t' remain  /
      xlen = len / (OPSIZ  8);
      while (xlen > 0)
        {
          ((op_t ) dstp)[0] = cccc;
          ((op_t ) dstp)[1] = cccc;
          ((op_t ) dstp)[2] = cccc;
          ((op_t ) dstp)[3] = cccc;
          ((op_t ) dstp)[4] = cccc;
          ((op_t ) dstp)[5] = cccc;
          ((op_t ) dstp)[6] = cccc;
          ((op_t ) dstp)[7] = cccc;
          dstp += 8  OPSIZ;
          xlen -= 1;
        }
      len %= OPSIZ  8;
 
      / Write 1 `op_t' per iteration until less than OPSIZ bytes remain  /
      xlen = len / OPSIZ;
      while (xlen > 0)
        {
          ((op_t ) dstp)[0] = cccc;
          dstp += OPSIZ;
          xlen -= 1;
        }
      len %= OPSIZ;
    }
 
  / Write the last few bytes  /
  while (len > 0)
    {
      ((unsigned char ) dstp)[0] = c;
      dstp += 1;
      len -= 1;
    }
 
  return dstpp;
}        CODESEG
 
    extrn   _VEC_memzero:near
    extrn   __sse2_available:dword
 
        public  memset
memset proc \
        dst:ptr byte, \
        value:byte, \
        count:dword
 
        OPTION PROLOGUE:NONE, EPILOGUE:NONE
 
        FPO    ( 0, 3, 0, 0, 0, 0 )
 
        mov     edx,[esp + 0ch] ; edx = "count"
        mov     ecx,[esp + 4]   ; ecx points to "dst"
 
        test    edx,edx         ; 0
        jz      short toend     ; if so, nothing to do
 
        xor     eax,eax
        mov     al,[esp + 8]    ; the byte "value" to be stored
 
; Special case large block zeroing using SSE2 support
    test    al,al ; memset using zero initializer
    jne     dword_align
    cmp     edx,0100h ; block size exceeds size threshold
    jb      dword_align
    cmp     DWORD PTR __sse2_available,0 ; SSE2 supported
    je      dword_align
 
    jmp     _VEC_memzero ; use fast zero SSE2 implementation
    ; no return
 
; Align address on dword boundary
dword_align:
 
        push    edi             ; preserve edi
        mov     edi,ecx         ; edi = dest pointer
 
        cmp     edx,4           ; if it's less then 4 bytes
        jb      tail            ; tail needs edi and edx to be initialized
 
        neg     ecx
        and     ecx,3           ; ecx = # bytes before dword boundary
        jz      short dwords    ; jump if address already aligned
 
        sub     edx,ecx         ; edx = adjusted count (for later)
adjust_loop:
        mov     [edi],al
        add     edi,1
        sub     ecx,1
        jnz     adjust_loop
 
dwords:
; set all 4 bytes of eax to [value]
        mov     ecx,eax         ; ecx=0/0/0/value
        shl     eax,8           ; eax=0/0/value/0
 
        add     eax,ecx         ; eax=0/0val/val
 
        mov     ecx,eax         ; ecx=0/0/val/val
 
        shl     eax,10h         ; eax=val/val/0/0
 
        add     eax,ecx         ; eax = all 4 bytes = [value]
 
; Set dword-sized blocks
        mov     ecx,edx         ; move original count to ecx
        and     edx,3           ; prepare in edx byte count (for tail loop)
        shr     ecx,2           ; adjust ecx to be dword count
        jz      tail            ; jump if it was less then 4 bytes
 
        rep     stosd
main_loop_tail:
        test    edx,edx         ; if there is no tail bytes,
        jz      finish          ; we finish, and it's time to leave
; Set remaining bytes
 
tail:
        mov     [edi],al        ; set remaining bytes
        add     edi,1
 
        sub     edx,1           ; if there is some more bytes
        jnz     tail            ; continue to fill them
 
; Done
finish:
        mov     eax,[esp + 8]   ; return dest pointer
        pop     edi             ; restore edi
 
        ret
 
toend:
        mov     eax,[esp + 4]   ; return dest pointer
 
        ret
 
memset  endp
 
        end

可以调用DS的OPEN vi, 连接可以输入类似于 dstp://192168111/Item00 其中192168111为DataSocket server的IP地址, Item00 为将要被读写的对象


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/13480282.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-08-15
下一篇 2023-08-15

发表评论

登录后才能评论

评论列表(0条)

保存