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

```asm
<nasm_unquote>:
  endbr64
  movzbl (%rdi),%edx
  mov    $0x0,%eax
  test   %dl,%dl
  je     L488
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %rdi,%rbp
  mov    %rsi,%r12
  lea    0x1(%rdi),%rbx
  cmp    $0x27,%dl
  je     L410
  cmp    $0x60,%dl
  je     L235
  cmp    $0x22,%dl
  je     L410
  mov    $0x0,%esi
  call   <strchr@plt>
  mov    %rax,%rbx
  mov    %rax,%rdi
  jmp    L648
L235:
  movzbl 0x1(%rdi),%edx
  test   %dl,%dl
  je     L648
  mov    $0x0,%r15d
  movl   $0x0,0xc(%rsp)
  mov    $0x0,%ecx
  movq   $0x0,(%rsp)
  lea    D16(%rip),%r13
  jmp    L578
L410:
  movzbl 0x1(%rbp),%eax
  cmp    %al,%dl
  je     L179
  test   %al,%al
  je     L179
L94:
  add    $0x1,%rbx
  lea    -0x1(%rbx),%rdi
  mov    %al,-0x2(%rbx)
  movzbl (%rbx),%eax
  cmp    %al,%dl
  je     L183
  test   %al,%al
  jne    L94
L183:
  movb   $0x0,(%rdi)
L648:
  test   %r12,%r12
  je     L180
  mov    %rbx,(%r12)
L180:
  mov    %rdi,%rax
  sub    %rbp,%rax
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L179:
  mov    %rbp,%rdi
  jmp    L183
  cmp    $0x5c,%dl
  je     L149
  cmp    $0x60,%dl
  je     L648
  mov    %dl,(%rdi)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  jmp    L380
  lea    -0x30(%rdx),%eax
  cmp    $0x48,%al
  ja     L666
  movzbl %al,%eax
  lea    D1(%rip),%rsi
  movslq (%rsi,%rax,4),%rax
  add    %rsi,%rax
  notrack jmp *%rax
  mov    %r14,(%rsp)
  mov    %r14,%rbx
  mov    $0x0,%r15d
  movl   $0x8,0xc(%rsp)
  mov    $0x4,%ecx
  jmp    L380
  movb   $0x7,(%rdi)
  mov    %r14,(%rsp)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  mov    $0x0,%r15d
  mov    $0x0,%ecx
  jmp    L380
  movb   $0x8,(%rdi)
  mov    %r14,(%rsp)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  mov    $0x0,%r15d
  mov    $0x0,%ecx
  jmp    L380
  movb   $0x1b,(%rdi)
  mov    %r14,(%rsp)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  mov    $0x0,%r15d
  mov    $0x0,%ecx
  jmp    L380
  movb   $0xc,(%rdi)
  mov    %r14,(%rsp)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  mov    $0x0,%r15d
  mov    $0x0,%ecx
  jmp    L380
  movb   $0xa,(%rdi)
  mov    %r14,(%rsp)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  mov    $0x0,%r15d
  mov    $0x0,%ecx
  jmp    L380
  movb   $0xd,(%rdi)
  mov    %r14,(%rsp)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  mov    $0x0,%r15d
  mov    $0x0,%ecx
  jmp    L380
  movb   $0x9,(%rdi)
  mov    %r14,(%rsp)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  mov    $0x0,%r15d
  mov    $0x0,%ecx
  jmp    L380
  movb   $0xb,(%rdi)
  mov    %r14,(%rsp)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  mov    $0x0,%r15d
  mov    $0x0,%ecx
  jmp    L380
  mov    %r14,(%rsp)
  mov    %r14,%rbx
  mov    $0x0,%r15d
  movl   $0x2,0xc(%rsp)
  mov    $0x2,%ecx
  jmp    L380
  movsbl %dl,%edx
  lea    -0x30(%rdx),%r15d
  mov    %r14,(%rsp)
  mov    %r14,%rbx
  movl   $0x2,0xc(%rsp)
  mov    $0x3,%ecx
  jmp    L380
L666:
  mov    %dl,(%rdi)
  mov    %r14,(%rsp)
  lea    0x1(%rdi),%rdi
  mov    %r14,%rbx
  mov    $0x0,%r15d
  mov    $0x0,%ecx
  jmp    L380
  lea    -0x30(%rdx),%eax
  cmp    $0x7,%al
  ja     L188
  movsbl %dl,%edx
  lea    -0x30(%rdx,%r15,8),%r15d
  mov    %r14,%rbx
  subl   $0x1,0xc(%rsp)
  jne    L380
  mov    %r15b,(%rdi)
  lea    0x1(%rdi),%rdi
  mov    $0x0,%ecx
  jmp    L380
L188:
  mov    %r15b,(%rdi)
  lea    0x1(%rdi),%rdi
  mov    $0x0,%ecx
  jmp    L380
  mov    %edx,%eax
  and    $0xffffffdf,%eax
  sub    $0x41,%eax
  cmp    $0x5,%al
  jbe    L266
  lea    -0x30(%rdx),%eax
  cmp    $0x9,%al
  jbe    L266
  cmp    (%rsp),%rbx
  jbe    L525
  mov    %r15d,%eax
  jmp    L449
L266:
  shl    $0x4,%r15d
  cmp    $0x60,%dl
  jle    L313
  movsbl %dl,%edx
  sub    $0x57,%edx
L234:
  add    %edx,%r15d
  mov    %r14,%rbx
  subl   $0x1,0xc(%rsp)
  jne    L380
  mov    %r15b,(%rdi)
  lea    0x1(%rdi),%rdi
  mov    $0x0,%ecx
  jmp    L380
L313:
  cmp    $0x40,%dl
  jle    L382
  movsbl %dl,%edx
  sub    $0x37,%edx
  jmp    L234
L382:
  movsbl %dl,%edx
  sub    $0x30,%edx
  jmp    L234
L525:
  mov    (%rsp),%rax
  movzbl -0x1(%rax),%eax
L449:
  mov    %al,(%rdi)
  lea    0x1(%rdi),%rdi
  mov    $0x0,%ecx
  jmp    L380
  mov    %edx,%eax
  and    $0xffffffdf,%eax
  sub    $0x41,%eax
  cmp    $0x5,%al
  jbe    L602
  lea    -0x30(%rdx),%eax
  cmp    $0x9,%al
  jbe    L602
  cmp    (%rsp),%rbx
  ja     L387
  mov    (%rsp),%rax
  movzbl -0x1(%rax),%eax
  mov    %al,(%rdi)
  lea    0x1(%rdi),%rdi
  mov    $0x0,%ecx
  jmp    L380
L602:
  shl    $0x4,%r15d
  cmp    $0x60,%dl
  jle    L136
  movsbl %dl,%edx
  sub    $0x57,%edx
L611:
  add    %edx,%r15d
  mov    %r14,%rbx
  subl   $0x1,0xc(%rsp)
  je     L239
L380:
  movzbl (%rbx),%edx
  test   %dl,%dl
  je     L216
L578:
  lea    0x1(%rbx),%r14
  cmp    $0x4,%ecx
  ja     L552
  mov    %ecx,%eax
  movslq 0x0(%r13,%rax,4),%rax
  add    %r13,%rax
  notrack jmp *%rax
L136:
  cmp    $0x40,%dl
  jle    L40
  movsbl %dl,%edx
  sub    $0x37,%edx
  jmp    L611
L40:
  movsbl %dl,%edx
  sub    $0x30,%edx
  jmp    L611
L239:
  mov    %r15d,%esi
  call   <emit_utf8@plt>
  mov    %rax,%rdi
  mov    $0x0,%ecx
  jmp    L380
L387:
  mov    %r15d,%esi
  call   <emit_utf8@plt>
  mov    %rax,%rdi
  mov    $0x0,%ecx
  jmp    L380
L552:
  mov    %r14,%rbx
  jmp    L380
L149:
  mov    %r14,%rbx
  mov    $0x1,%ecx
  jmp    L380
  mov    %r14,(%rsp)
  mov    %r14,%rbx
  mov    $0x0,%r15d
  movl   $0x4,0xc(%rsp)
  mov    $0x4,%ecx
  jmp    L380
L216:
  cmp    $0x3,%ecx
  je     L600
  cmp    $0x4,%ecx
  je     L628
  cmp    $0x2,%ecx
  jne    L648
  mov    (%rsp),%rax
  cmp    %rax,%rbx
  ja     L586
  movzbl -0x1(%rax),%r15d
L586:
  mov    %r15b,(%rdi)
  lea    0x1(%rdi),%rdi
  jmp    L648
L600:
  mov    %r15b,(%rdi)
  lea    0x1(%rdi),%rdi
  jmp    L648
L628:
  cmp    (%rsp),%rbx
  ja     L400
  mov    (%rsp),%rax
  movzbl -0x1(%rax),%eax
  mov    %al,(%rdi)
  lea    0x1(%rdi),%rdi
  jmp    L648
L400:
  mov    %r15d,%esi
  call   <emit_utf8@plt>
  mov    %rax,%rdi
  jmp    L648
L488:
  ret
```

assistant: ```c
size_t nasm_unquote(char *str, char **ep) {
  char bq;
  char *p, *q;
  char *escp = NULL;
  char c;
  enum unq_state {
    st_start,
    st_backslash,
    st_hex,
    st_oct,
    st_ucs,
  } state;
  int ndig = 0;
  int32_t nval = 0;
  p = q = str;
  bq = *p++;
  if (!bq)
    return 0;
  switch (bq) {
  case '\'':
  case '\"':
    while ((c = *p) && c != bq) {
      p++;
      *q++ = c;
    }
    *q = '\0';
    break;
  case '`':
    state = st_start;
    while ((c = *p)) {
      p++;
      switch (state) {
      case st_start:
        switch (c) {
        case '\\':
          state = st_backslash;
          break;
        case '`':
          p--;
          goto out;
        default:
          *q++ = c;
          break;
        }
        break;
      case st_backslash:
        state = st_start;
        escp = p;
        nval = 0;
        switch (c) {
        case 'a':
          *q++ = 7;
          break;
        case 'b':
          *q++ = 8;
          break;
        case 'e':
          *q++ = 27;
          break;
        case 'f':
          *q++ = 12;
          break;
        case 'n':
          *q++ = 10;
          break;
        case 'r':
          *q++ = 13;
          break;
        case 't':
          *q++ = 9;
          break;
        case 'u':
          state = st_ucs;
          ndig = 4;
          break;
        case 'U':
          state = st_ucs;
          ndig = 8;
          break;
        case 'v':
          *q++ = 11;
          break;
        case 'x':
        case 'X':
          state = st_hex;
          ndig = 2;
          break;
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
          state = st_oct;
          ndig = 2;
          nval = c - '0';
          break;
        default:
          *q++ = c;
          break;
        }
        break;
      case st_oct:
        if (c >= '0' && c <= '7') {
          nval = (nval << 3) + (c - '0');
          if (!--ndig) {
            *q++ = nval;
            state = st_start;
          }
        } else {
          p--;
          *q++ = nval;
          state = st_start;
        }
        break;
      case st_hex:
        if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
          nval = (nval << 4) + ((c) >= 'a' ? (c) - 'a' + 10 : (c) >= 'A' ? (c) - 'A' + 10 : (c) - '0');
          if (!--ndig) {
            *q++ = nval;
            state = st_start;
          }
        } else {
          p--;
          *q++ = (p > escp) ? nval : escp[-1];
          state = st_start;
        }
        break;
      case st_ucs:
        if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
          nval = (nval << 4) + ((c) >= 'a' ? (c) - 'a' + 10 : (c) >= 'A' ? (c) - 'A' + 10 : (c) - '0');
          if (!--ndig) {
            q = emit_utf8(q, nval);
            state = st_start;
          }
        } else {
          p--;
          if (p > escp)
            q = emit_utf8(q, nval);
          else
            *q++ = escp[-1];
          state = st_start;
        }
        break;
      }
    }
    switch (state) {
    case st_start:
    case st_backslash:
      break;
    case st_oct:
      *q++ = nval;
      break;
    case st_hex:
      *q++ = (p > escp) ? nval : escp[-1];
      break;
    case st_ucs:
      if (p > escp)
        q = emit_utf8(q, nval);
      else
        *q++ = escp[-1];
      break;
    }
  out:
    break;
  default:
    p = q = strchr(str, '\0');
    break;
  }
  if (ep)
    *ep = p;
  return q - str;
}
```