user: 请将以下的汇编代码转换成C语言代码：

```asm
<highCharToUnicode>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x48,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x18(%rbp)
  xor    %eax,%eax
  movq   $0x0,-0x28(%rbp)
  movb   $0x0,-0x2a(%rbp)
  movb   $0x0,-0x29(%rbp)
  movw   $0x0,-0x1a(%rbp)
  cmpq   $0x3,-0x40(%rbp)
  jne    L48
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  shl    $0x4,%eax
  mov    %al,-0x1a(%rbp)
  movzbl -0x1a(%rbp),%eax
  mov    %eax,%edx
  mov    -0x38(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  sar    $0x2,%al
  and    $0xf,%eax
  or     %edx,%eax
  mov    %al,-0x1a(%rbp)
  mov    -0x38(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  shl    $0x6,%eax
  mov    %al,-0x19(%rbp)
  movzbl -0x19(%rbp),%eax
  mov    %eax,%edx
  mov    -0x38(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  and    $0x3f,%eax
  or     %edx,%eax
  mov    %al,-0x19(%rbp)
  jmp    L40
L48:
  cmpq   $0x2,-0x40(%rbp)
  jne    L70
  movzbl -0x1a(%rbp),%eax
  mov    %eax,%edx
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  sar    $0x2,%al
  and    $0xf,%eax
  or     %edx,%eax
  mov    %al,-0x1a(%rbp)
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  shl    $0x6,%eax
  mov    %al,-0x19(%rbp)
  movzbl -0x19(%rbp),%eax
  mov    %eax,%edx
  mov    -0x38(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  and    $0x3f,%eax
  or     %edx,%eax
  mov    %al,-0x19(%rbp)
  jmp    L40
L70:
  mov    $0x0,%eax
  jmp    L11
L40:
  mov    -0x48(%rbp),%rax
  movq   $0x6,(%rax)
  mov    $0x6,%edi
  call   <malloc@plt>
  mov    %rax,-0x28(%rbp)
  cmpq   $0x0,-0x28(%rbp)
  jne    L0
  mov    $0x0,%eax
  jmp    L11
L0:
  mov    -0x28(%rbp),%rax
  movb   $0x5c,(%rax)
  mov    -0x28(%rbp),%rax
  add    $0x1,%rax
  movb   $0x75,(%rax)
  movzbl -0x1a(%rbp),%eax
  shr    $0x4,%al
  mov    %al,-0x2a(%rbp)
  movzbl -0x1a(%rbp),%eax
  movzbl -0x2a(%rbp),%edx
  shl    $0x4,%edx
  sub    %edx,%eax
  mov    %al,-0x29(%rbp)
  movzbl -0x2a(%rbp),%eax
  mov    -0x28(%rbp),%rdx
  lea    0x2(%rdx),%rbx
  mov    %eax,%edi
  call   <valueToHexDigit@plt>
  mov    %al,(%rbx)
  movzbl -0x29(%rbp),%eax
  mov    -0x28(%rbp),%rdx
  lea    0x3(%rdx),%rbx
  mov    %eax,%edi
  call   <valueToHexDigit@plt>
  mov    %al,(%rbx)
  movzbl -0x19(%rbp),%eax
  shr    $0x4,%al
  mov    %al,-0x2a(%rbp)
  movzbl -0x19(%rbp),%eax
  movzbl -0x2a(%rbp),%edx
  shl    $0x4,%edx
  sub    %edx,%eax
  mov    %al,-0x29(%rbp)
  movzbl -0x2a(%rbp),%eax
  mov    -0x28(%rbp),%rdx
  lea    0x4(%rdx),%rbx
  mov    %eax,%edi
  call   <valueToHexDigit@plt>
  mov    %al,(%rbx)
  movzbl -0x29(%rbp),%eax
  mov    -0x28(%rbp),%rdx
  lea    0x5(%rdx),%rbx
  mov    %eax,%edi
  call   <valueToHexDigit@plt>
  mov    %al,(%rbx)
  mov    -0x28(%rbp),%rax
L11:
  mov    -0x18(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L7
  call   <__stack_chk_fail@plt>
L7:
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

assistant: ```c
char *highCharToUnicode(const char *str, size_t inlen, size_t *outlen) {
  char *out = NULL;
  unsigned char higherDigit = 0;
  unsigned char lowerDigit = 0;
  unsigned char plane[2] = {0, 0};
  if (inlen == 3) {
    plane[0] = str[0] << 4;
    plane[0] |= ((str[1] >> 2) & 15);
    plane[1] = str[1] << 6;
    plane[1] |= (str[2] & 63);
  } else if (inlen == 2) {
    plane[0] |= ((str[0] >> 2) & 15);
    plane[1] = str[0] << 6;
    plane[1] |= (str[1] & 63);
  } else {
    return NULL;
  }
  *outlen = 6;
  out = malloc(sizeof(char) * 6);
  if (out == NULL) {
    return NULL;
  }
  out[0] = '\\';
  out[1] = 'u';
  higherDigit = (unsigned char)plane[0] / 16;
  lowerDigit = plane[0] - (higherDigit * 16);
  out[2] = valueToHexDigit(higherDigit);
  out[3] = valueToHexDigit(lowerDigit);
  higherDigit = (unsigned char)plane[1] / 16;
  lowerDigit = plane[1] - (higherDigit * 16);
  out[4] = valueToHexDigit(higherDigit);
  out[5] = valueToHexDigit(lowerDigit);
  return out;
}
```