string.c void* memset(void *dst, int c, uint n)

トップページ
jupiteroak.hatenablog.com


string.c
https://github.com/mit-pdos/xv6-public/blob/master/string.c#L4

void* memset(void *dst, int c, uint n)
{
  if ((int)dst%4 == 0 && n%4 == 0){
    c &= 0xFF;
    stosl(dst, (c<<24)|(c<<16)|(c<<8)|c, n/4);
  } else
    stosb(dst, c, n);
  return dst;
}

memset関数は、先頭アドレスが引数dst・サイズが引数nのメモリ領域を、引数cで指定された値を使って初期化します(特定のメモリ領域を指定された値で埋めます)。

引数 dst
初期化の対象となるメモリ領域の先頭アドレスです。

引数 c
初期化で使用される値です。ただし、実際に使用されるのは下位8bitの値だけです。

引数 n
初期化の対象となるメモリ領域のサイズ(バイト単位)です。

戻り値
引数dstです。


処理の内容

アドレスdstが4バイト境界にある かつ サイズnの値が4バイトの倍数値である場合

if ((int)dst%4 == 0 && n%4 == 0){
    c &= 0xFF;
    stosl(dst, (c<<24)|(c<<16)|(c<<8)|c, n/4);
  } 

引数dstで指定されたアドレスが4バイト境界(4バイトの倍数値)、かつ、引数nで指定されたサイズが4バイトの倍数値となる場合の処理です。

stosl関数を呼び出す

stosl関数を呼び出して、先頭アドレスが引数dst・サイズが引数n×4のメモリ領域を、引数cの下位8bitの値のみから構成される4バイトの値( (c<<24)|(c<<16)|(c<<8)|c )を使って、初期化します。
引数cの下位8bitの値のみから構成される4バイトの値を取得するために、0xFFをビット積代入してから、(c<<24)|(c<<16)|(c<<8)|c の演算を行なっています。

式の評価
c 0x●●○○△△XX
c &= 0xFF 0x0000 00XX
c<<8 0x0000 XX00
c<<16 0x00XX 0000
c<<24 0xXX00 0000
(c<<24) | (c<<16) | (c<<8) | c 0xXXXX XXXX

上記以外の場合

} else
    stosb(dst, c, n);

stosb関数を呼び出す

stosb関数を呼び出して、先頭アドレスが引数dst・サイズが引数cntのメモリ領域を、引数cの下位8bitの値を使って初期化します。

return dst;

引数dst(アドレス)を戻り値として、リターンします。