user: 请显示与下面列出的汇编代码相匹配的C语言实现:

```asm
<cmd_getid>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %edi,-0x24(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    $0x0,%eax
  call   <getuid@plt>
  mov    %rax,%rsi
  lea    D23(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0x0,%eax
  call   <getuid@plt>
  mov    %eax,%edi
  call   <getpwuid@plt>
  mov    %rax,-0x20(%rbp)
  cmpq   $0x0,-0x20(%rbp)
  je     L43
  mov    -0x20(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rsi
  lea    D51(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L43:
  mov    $0x0,%eax
  call   <getgid@plt>
  mov    %rax,%rsi
  lea    D21(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0x0,%eax
  call   <getgid@plt>
  mov    %eax,%edi
  call   <getgrgid@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L14
  mov    -0x18(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rsi
  lea    D51(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L14:
  mov    $0x0,%eax
  call   <geteuid@plt>
  movslq %eax,%rbx
  mov    $0x0,%eax
  call   <getuid@plt>
  cmp    %rax,%rbx
  je     L27
  mov    $0x0,%eax
  call   <geteuid@plt>
  mov    %eax,%esi
  lea    D7(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0x0,%eax
  call   <geteuid@plt>
  mov    %eax,%edi
  call   <getpwuid@plt>
  mov    %rax,-0x20(%rbp)
  cmpq   $0x0,-0x20(%rbp)
  je     L27
  mov    -0x20(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rsi
  lea    D51(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L27:
  mov    $0x0,%eax
  call   <getegid@plt>
  movslq %eax,%rbx
  mov    $0x0,%eax
  call   <getgid@plt>
  cmp    %rax,%rbx
  je     L11
  mov    $0x0,%eax
  call   <getegid@plt>
  mov    %eax,%esi
  lea    D24(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0x0,%eax
  call   <getegid@plt>
  mov    %eax,%edi
  call   <getgrgid@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L11
  mov    -0x18(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rsi
  lea    D51(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L11:
  mov    $0xa,%edi
  call   <putchar@plt>
  nop
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

tool_calls: name: parse_data
arguments: data_label: D23
data_type: string
name: parse_data
arguments: data_label: D51
data_type: string
name: parse_data
arguments: data_label: D21
data_type: string
name: parse_data
arguments: data_label: D7
data_type: string
name: parse_data
arguments: data_label: D24
data_type: string

tool: D23: uid=%u

tool: D51: (%s)

tool: D21:  gid=%u

tool: D7:  euid=%u

tool: D24:  egid=%u

assistant: ```c
void cmd_getid(int argc, char *argv[]) {
  struct passwd *pwd;
  struct group *grp;
  printf("uid=%u", getuid());
  if ((pwd = getpwuid(getuid())) != NULL)
    printf("(%s)", pwd->pw_name);
  printf(" gid=%u", getgid());
  if ((grp = getgrgid(getgid())) != NULL)
    printf("(%s)", grp->gr_name);
  if (geteuid() != getuid()) {
    printf(" euid=%u", geteuid());
    if ((pwd = getpwuid(geteuid())) != NULL)
      printf("(%s)", pwd->pw_name);
  }
  if (getegid() != getgid()) {
    printf(" egid=%u", getegid());
    if ((grp = getgrgid(getegid())) != NULL)
      printf("(%s)", grp->gr_name);
  }
  printf("\n");
}
```