user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<purify_special_char>:
  endbr64
  push   %r14
  mov    %rdi,%r14
  xor    %edi,%edi
  push   %r13
  mov    %rdx,%r13
  push   %r12
  mov    %rsi,%r12
  push   %rbp
  push   %rbx
  movslq (%rsi),%rax
  cmpb   $0x7b,(%r14,%rax,1)
  jne    L141
  xor    %edi,%edi
  cmpb   $0x5c,0x1(%r14,%rax,1)
  sete   %dil
L141:
  call   <assert@plt>
  mov    (%r12),%eax
  lea    0x2(%rax),%ebp
  mov    %ebp,(%r12)
  movslq %ebp,%rbp
L58:
  movsbl (%r14,%rbp,1),%edi
  mov    %ebp,%ebx
  add    $0x1,%rbp
  call   <isalpha@plt>
  test   %rax,%rax
  jne    L58
  mov    (%r12),%esi
  mov    %r14,%rdi
  cmp    %ebx,%esi
  lea    0x1(%rsi),%eax
  cmove  %eax,%ebx
  xor    %ecx,%ecx
  mov    %ebx,%edx
  call   <foreign_letter@plt>
  test   %rax,%rax
  jne    L147
  mov    %ebx,(%r12)
L120:
  movslq %ebx,%rax
  mov    $0x1,%ebp
  movsbl (%r14,%rax,1),%edi
  test   %dil,%dil
  jne    L109
  jmp    L76
  xchg   %ax,%ax
L83:
  call   <isalpha@plt>
  test   %rax,%rax
  je     L130
  movslq (%r12),%rdx
  lea    0x1(%rdx),%eax
  mov    %eax,(%r12)
  movslq 0x0(%r13),%rax
  lea    0x1(%rax),%ecx
  mov    %ecx,0x0(%r13)
  movzbl (%r14,%rdx,1),%edx
  mov    %dl,(%r14,%rax,1)
  mov    (%r12),%ebx
L62:
  movslq %ebx,%rax
  movsbl (%r14,%rax,1),%edi
  test   %dil,%dil
  je     L76
L109:
  cmp    $0x7b,%dil
  je     L55
  cmp    $0x7d,%dil
  jne    L83
  sub    $0x1,%ebp
  je     L76
  add    $0x1,%ebx
  movslq %ebx,%rax
  mov    %ebx,(%r12)
  movsbl (%r14,%rax,1),%edi
  test   %dil,%dil
  jne    L109
L76:
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  ret
  nopl   0x0(%rax,%rax,1)
L55:
  add    $0x1,%ebx
  add    $0x1,%ebp
  mov    %ebx,(%r12)
  jmp    L62
  nopl   0x0(%rax)
L130:
  mov    (%r12),%eax
  lea    0x1(%rax),%ebx
  mov    %ebx,(%r12)
  jmp    L62
  nopl   (%rax)
L147:
  mov    %ebx,%eax
  sub    (%r12),%eax
  xor    %edi,%edi
  sub    $0x1,%eax
  cmp    $0x1,%eax
  setbe  %dil
  call   <assert@plt>
  movslq (%r12),%rdx
  lea    0x1(%rdx),%eax
  mov    %eax,(%r12)
  movslq 0x0(%r13),%rax
  lea    0x1(%rax),%ecx
  mov    %ecx,0x0(%r13)
  movzbl (%r14,%rdx,1),%edx
  mov    %dl,(%r14,%rax,1)
  movslq (%r12),%rax
  cmp    %ebx,%eax
  jl     L144
  mov    %eax,%ebx
  jmp    L120
L144:
  lea    0x1(%rax),%edx
  mov    %edx,(%r12)
  movsbl (%r14,%rax,1),%edi
  movslq 0x0(%r13),%rax
  lea    0x1(%rax),%edx
  lea    (%r14,%rax,1),%rbx
  mov    %edx,0x0(%r13)
  call   <tolower@plt>
  mov    %al,(%rbx)
  mov    (%r12),%ebx
  jmp    L120
```

assistant: ```c
void purify_special_char(char *str, int *src, int *dst) {
  int depth;
  int peek;
  assert(str[*src] == '{' && str[*src + 1] == '\\');
  depth = 1;
  *src += 2;
  peek = *src;
  while (isalpha(str[peek]))
    peek++;
  if (peek == *src)
    peek++;
  if (foreign_letter(str, *src, peek, NULL)) {
    assert(peek - *src == 1 || peek - *src == 2);
    str[(*dst)++] = str[(*src)++];
    if (*src < peek)
      str[(*dst)++] = tolower(str[(*src)++]);
  } else {
    *src = peek;
  }
  while (str[*src]) {
    switch (str[*src]) {
    case '{':
      depth++;
      (*src)++;
      break;
    case '}':
      depth--;
      if (depth == 0)
        return;
      (*src)++;
      break;
    default:
      if (isalpha(str[*src]))
        str[(*dst)++] = str[(*src)++];
      else
        (*src)++;
    }
  }
}
```