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

```asm
<soundex>:
  endbr64
  push   %r12
  lea    D57(%rip),%rsi
  push   %rbp
  push   %rbx
  mov    %rdi,%rbx
  add    $0xffffffffffffff80,%rsp
  movdqa D18(%rip),%xmm0
  mov    %fs:0x28,%rax
  mov    %rax,0x78(%rsp)
  xor    %eax,%eax
  mov    D30(%rip),%rax
  lea    0x73(%rsp),%rdi
  movaps %xmm0,(%rsp)
  movdqa D3(%rip),%xmm0
  mov    %rax,0x60(%rsp)
  movaps %xmm0,0x10(%rsp)
  movdqa D30(%rip),%xmm0
  movaps %xmm0,0x20(%rsp)
  movdqa D27(%rip),%xmm0
  movaps %xmm0,0x30(%rsp)
  movdqa D55(%rip),%xmm0
  movaps %xmm0,0x40(%rsp)
  movdqa D21(%rip),%xmm0
  movaps %xmm0,0x50(%rsp)
  call   <strcpy@plt>
  movsbl (%rbx),%edi
  test   %dil,%dil
  jne    L83
  jmp    L116
  cs nopw 0x0(%rax,%rax,1)
L37:
  movsbl 0x1(%rbx),%edi
  add    $0x1,%rbx
  test   %dil,%dil
  je     L116
L83:
  call   <isalpha@plt>
  test   %rax,%rax
  je     L37
  movsbl (%rbx),%edi
  test   %dil,%dil
  je     L116
  call   <toupper@plt>
  add    $0x1,%rbx
  mov    $0x1,%r12d
  mov    %al,0x73(%rsp)
  movsbl %al,%eax
  sub    $0x41,%eax
  cltq
  mov    (%rsp,%rax,4),%ebp
  jmp    L110
  nopl   0x0(%rax,%rax,1)
L35:
  add    $0x1,%rbx
  cmp    $0x4,%r12d
  je     L116
L110:
  movsbl (%rbx),%edi
  test   %dil,%dil
  je     L116
  call   <isalpha@plt>
  test   %rax,%rax
  je     L35
  movsbl (%rbx),%edi
  call   <tolower@plt>
  movsbl %al,%eax
  sub    $0x61,%eax
  cltq
  mov    (%rsp,%rax,4),%eax
  cmp    %ebp,%eax
  je     L35
  xor    %ebp,%ebp
  test   %eax,%eax
  je     L35
  movslq %r12d,%rdx
  lea    0x30(%rax),%ecx
  add    $0x1,%r12d
  mov    %eax,%ebp
  mov    %cl,0x73(%rsp,%rdx,1)
  add    $0x1,%rbx
  cmp    $0x4,%r12d
  jne    L110
  nopl   0x0(%rax,%rax,1)
L116:
  mov    0x78(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L11
  sub    $0xffffffffffffff80,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  ret
L11:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: unpack_data
arguments: data_label: D57
data_type: string
name: unpack_data
arguments: data_label: D18
data_type: byte[16]
name: unpack_data
arguments: data_label: D30
data_type: byte[16]
name: unpack_data
arguments: data_label: D3
data_type: byte[16]
name: unpack_data
arguments: data_label: D27
data_type: byte[16]
name: unpack_data
arguments: data_label: D55
data_type: byte[16]
name: unpack_data
arguments: data_label: D21
data_type: byte[16]

tool: D57: Z000

tool: {"D18": [0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00]}

tool: {"D30": [0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0x00]}

tool: {"D3": [0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00]}

tool: {"D27": [0x05,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00]}

tool: {"D55": [0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00]}

tool: {"D21": [0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00]}

assistant: ```c
char *soundex(char *in) {
  int code[] = {0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2};
  char key[5], ch;
  int last, count;
  strcpy(key, "Z000");
  while (*in != '\0' && !isalpha(*in))
    ++in;
  if (*in == '\0')
    return key;
  key[0] = toupper(*in);
  last = code[key[0] - 'A'];
  ++in;
  for (count = 1; count < 4 && *in != '\0'; ++in) {
    if (isalpha(*in)) {
      ch = tolower(*in);
      if (last != code[ch - 'a']) {
        last = code[ch - 'a'];
        if (last != 0)
          key[count++] = '0' + last;
      }
    }
  }
  return key;
}
```