user: 这段汇编代码用C语言表示是什么样的?

```asm
<_digest_to_hex>:
  endbr64
  sub    $0x28,%rsp
  movdqa D0(%rip),%xmm0
  mov    %fs:0x28,%rcx
  mov    %rcx,0x18(%rsp)
  xor    %ecx,%ecx
  movzbl (%rdi),%ecx
  movb   $0x0,0x10(%rsp)
  movaps %xmm0,(%rsp)
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,(%rsi)
  movzbl (%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x1(%rsi)
  movzbl 0x1(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x2(%rsi)
  movzbl 0x1(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x3(%rsi)
  movzbl 0x2(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x4(%rsi)
  movzbl 0x2(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x5(%rsi)
  movzbl 0x3(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x6(%rsi)
  movzbl 0x3(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x7(%rsi)
  movzbl 0x4(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x8(%rsi)
  movzbl 0x4(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x9(%rsi)
  movzbl 0x5(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0xa(%rsi)
  movzbl 0x5(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0xb(%rsi)
  movzbl 0x6(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0xc(%rsi)
  movzbl 0x6(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0xd(%rsi)
  movzbl 0x7(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0xe(%rsi)
  movzbl 0x7(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0xf(%rsi)
  movzbl 0x8(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x10(%rsi)
  movzbl 0x8(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x11(%rsi)
  movzbl 0x9(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x12(%rsi)
  movzbl 0x9(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x13(%rsi)
  movzbl 0xa(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x14(%rsi)
  movzbl 0xa(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x15(%rsi)
  movzbl 0xb(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x16(%rsi)
  movzbl 0xb(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x17(%rsi)
  movzbl 0xc(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x18(%rsi)
  movzbl 0xc(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x19(%rsi)
  movzbl 0xd(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x1a(%rsi)
  movzbl 0xd(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x1b(%rsi)
  movzbl 0xe(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x1c(%rsi)
  movzbl 0xe(%rdi),%ecx
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x1d(%rsi)
  movzbl 0xf(%rdi),%ecx
  shr    $0x4,%cl
  and    $0xf,%ecx
  movzbl (%rsp,%rcx,1),%ecx
  mov    %cl,0x1e(%rsi)
  movzbl 0xf(%rdi),%edx
  and    $0xf,%edx
  movzbl (%rsp,%rdx,1),%edx
  mov    %dl,0x1f(%rsi)
  mov    0x18(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L9
  add    $0x28,%rsp
  ret
L9:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: unpack_data
arguments: label: D0
type_infered: byte[16]

tool: {"D0": [0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66]}

assistant: ```c
void _digest_to_hex(const char *digest, char *hex) {
  int i;
  const char hexdigit[] = "0123456789abcdef";
  for (i = 0; i < 16; i++) {
    *hex++ = hexdigit[(digest[i] >> 4) & 0x0F];
    *hex++ = hexdigit[digest[i] & 0x0F];
  }
}
```