UEFITIPS:BASE_LIST 用法

最近又在开关于Debug Message的内容,因此研究了一下BASE_LIST。简单的说,有时候你要传递一些长度不定的数据就可以使用这个定义。比如,一个数据块,有时候其中有10个UINTN,有时候其中有2个UINTN (特别注意的是每个单元的大小必须相同)。

具体结构体定义在 Edk2\MdePkg\Include\Base.h,可以看到BASE_LIST 实际上是一个指向 UINTN 的指针。

///
/// Pointer to the start of a variable argument list stored in a memory buffer. Same as UINT8 *.
///
typedef UINTN *BASE_LIST;

此外,经常和 BASE_ARG 结合起来使用,这个宏会返回指针指向的下一个值:

/**
  Returns an argument of a specified type from a variable argument list and updates
  the pointer to the variable argument list to point to the next argument.

  This function returns an argument of the type specified by TYPE from the beginning
  of the variable argument list specified by Marker.  Marker is then updated to point
  to the next argument in the variable argument list.  The method for computing the
  pointer to the next argument in the argument list is CPU specific following the EFIAPI ABI.

  @param   Marker   The pointer to the beginning of a variable argument list.
  @param   TYPE     The type of argument to retrieve from the beginning
                    of the variable argument list.

  @return  An argument of the type specified by TYPE.

**/
#define BASE_ARG(Marker, TYPE)  (*(TYPE *) ((Marker += _BASE_INT_SIZE_OF (TYPE)) - _BASE_INT_SIZE_OF (TYPE)))

编写代码验证:

#include  <Uefi.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>

INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
  UINTN A[4]={1,2,3,4};
  BASE_LIST TestList;
  
  TestList=(BASE_LIST) &A;
  
  for (int i=0;i<4;i++) {
	  Print(L"%d ",BASE_ARG(TestList,UINTN));
  }
   Print(L"\n");
  return(0);
}

运行结果:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注