pretty code

2019年7月22日 星期一

memset in UEFI

最近常常操作 unsigned long long 的 2 維陣列,故突發奇想,是否可以使用 memset 來 init 1 個大於 1byte 且非 0 的值呢?

上面是 C11 規格書中提到的 memset 定義,我們可以看到第 2 個參數雖然接受的是 1 個 int,但最後會轉成 1 個 unsigned char,故看起來應該是不行。

至於 UEFI 中的 memset 實作是在 Stdlib\LibC\String\Misc.c 中,細節如下,看起來應該是跟 Stanard C 一樣,會被轉成 unsigned char。

#if !((defined(MDE_CPU_ARM) || defined(MDE_CPU_AARCH64)) && defined(__GNUC__))
/** The memset function copies the value of c (converted to an unsigned char)
    into each of the first n characters of the object pointed to by s.

    @return   The memset function returns the value of s.
**/
void *
memset(void *s, int c, size_t n)
{
  return SetMem( s, (UINTN)n, (UINT8)c);
}
#endif

不過,UEFI 另外有 InternalMemSetMem64 的函數,其實作位於 MdePkg\Library\BaseMemoryLib\MemLibGeneric.c 中,看來我們可以使用這個函數。

/**
  Fills a target buffer with a 64-bit value, and returns the target buffer.

  @param  Buffer  The pointer to the target buffer to fill.
  @param  Length  The count of 64-bit value to fill.
  @param  Value   The value with which to fill Length bytes of Buffer.

  @return Buffer

**/
VOID *
EFIAPI
InternalMemSetMem64 (
  OUT     VOID                      *Buffer,
  IN      UINTN                     Length,
  IN      UINT64                    Value
  )
{
  for (; Length != 0; Length--) {
    ((UINT64*)Buffer)[Length - 1] = Value;
  }
  return Buffer;
}

沒有留言: