user: 下面的汇编指令对应的C源代码是什么：

```asm
<purify_special_char>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x7b,%al
  jne    L121
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  cltq
  lea    0x1(%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x5c,%al
  jne    L121
  mov    $0x1,%eax
  jmp    L167
L121:
  mov    $0x0,%eax
L167:
  mov    %eax,%edi
  call   <assert@plt>
  movl   $0x1,-0x18(%rbp)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  lea    0x2(%rax),%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x14(%rbp)
  jmp    L80
L106:
  addl   $0x1,-0x14(%rbp)
L80:
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isalpha@plt>
  test   %rax,%rax
  jne    L106
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  cmp    %eax,-0x14(%rbp)
  jne    L71
  addl   $0x1,-0x14(%rbp)
L71:
  mov    -0x30(%rbp),%rax
  mov    (%rax),%esi
  mov    -0x14(%rbp),%edx
  mov    -0x28(%rbp),%rax
  mov    $0x0,%ecx
  mov    %rax,%rdi
  call   <foreign_letter@plt>
  test   %rax,%rax
  je     L205
  mov    -0x30(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x14(%rbp),%eax
  sub    %edx,%eax
  cmp    $0x1,%eax
  je     L17
  mov    -0x30(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x14(%rbp),%eax
  sub    %edx,%eax
  cmp    $0x2,%eax
  jne    L64
L17:
  mov    $0x1,%eax
  jmp    L166
L64:
  mov    $0x0,%eax
L166:
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%ecx
  mov    -0x30(%rbp),%rdx
  mov    %ecx,(%rdx)
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  lea    (%rdx,%rax,1),%rsi
  mov    -0x38(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%ecx
  mov    -0x38(%rbp),%rdx
  mov    %ecx,(%rdx)
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rax,%rdx
  movzbl (%rsi),%eax
  mov    %al,(%rdx)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  cmp    %eax,-0x14(%rbp)
  jle    L122
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%ecx
  mov    -0x30(%rbp),%rdx
  mov    %ecx,(%rdx)
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movsbl %al,%edx
  mov    -0x38(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%esi
  mov    -0x38(%rbp),%rcx
  mov    %esi,(%rcx)
  movslq %eax,%rcx
  mov    -0x28(%rbp),%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %edx,%edi
  call   <tolower@plt>
  mov    %al,(%rbx)
  jmp    L122
L205:
  mov    -0x30(%rbp),%rax
  mov    -0x14(%rbp),%edx
  mov    %edx,(%rax)
  jmp    L122
L132:
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  cmp    $0x7b,%eax
  je     L22
  cmp    $0x7d,%eax
  je     L133
  jmp    L13
L22:
  addl   $0x1,-0x18(%rbp)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L122
L133:
  subl   $0x1,-0x18(%rbp)
  cmpl   $0x0,-0x18(%rbp)
  je     L154
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L122
L13:
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isalpha@plt>
  test   %rax,%rax
  je     L158
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%ecx
  mov    -0x30(%rbp),%rdx
  mov    %ecx,(%rdx)
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  lea    (%rdx,%rax,1),%rsi
  mov    -0x38(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%ecx
  mov    -0x38(%rbp),%rdx
  mov    %ecx,(%rdx)
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rax,%rdx
  movzbl (%rsi),%eax
  mov    %al,(%rdx)
  jmp    L122
L158:
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
L122:
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L132
  jmp    L151
L154:
  nop
L151:
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

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)++;
    }
  }
}
```