user: 请显示与下面列出的汇编代码相匹配的C语言实现:

```asm
<ctype_test>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    $0x41,%edi
  call   <isupper@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x61,%edi
  call   <isupper@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <isupper@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x0,%edi
  call   <isupper@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x41,%edi
  call   <islower@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x61,%edi
  call   <islower@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <islower@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x0,%edi
  call   <islower@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x41,%edi
  call   <isdigit@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x61,%edi
  call   <isdigit@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <isdigit@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x0,%edi
  call   <isdigit@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x41,%edi
  call   <isxdigit@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x61,%edi
  call   <isxdigit@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x68,%edi
  call   <isxdigit@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <isxdigit@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x0,%edi
  call   <isxdigit@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x20,%edi
  call   <isspace@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <isspace@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x0,%edi
  call   <isspace@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x41,%edi
  call   <isalpha@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x61,%edi
  call   <isalpha@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x68,%edi
  call   <isalpha@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <isalpha@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x0,%edi
  call   <isalpha@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x20,%edi
  call   <isprint@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x41,%edi
  call   <isprint@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x61,%edi
  call   <isprint@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x68,%edi
  call   <isprint@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <isprint@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x0,%edi
  call   <isprint@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x20,%edi
  call   <isgraph@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x41,%edi
  call   <isgraph@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x61,%edi
  call   <isgraph@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x68,%edi
  call   <isgraph@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <isgraph@plt>
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x0,%edi
  call   <isgraph@plt>
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x63,%edi
  call   <toupper@plt>
  cmp    $0x43,%al
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x43,%edi
  call   <toupper@plt>
  cmp    $0x43,%al
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <toupper@plt>
  cmp    $0x39,%al
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x63,%edi
  call   <tolower@plt>
  cmp    $0x63,%al
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x43,%edi
  call   <tolower@plt>
  cmp    $0x63,%al
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  mov    $0x39,%edi
  call   <tolower@plt>
  cmp    $0x39,%al
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <CT_ASSERT@plt>
  nop
  pop    %rbp
  ret
```

assistant: ```c
void ctype_test() {
  CT_ASSERT(isupper('A'));
  CT_ASSERT(!isupper('a'));
  CT_ASSERT(!isupper('9'));
  CT_ASSERT(!isupper('\000'));
  CT_ASSERT(!islower('A'));
  CT_ASSERT(islower('a'));
  CT_ASSERT(!islower('9'));
  CT_ASSERT(!islower('\000'));
  CT_ASSERT(!isdigit('A'));
  CT_ASSERT(!isdigit('a'));
  CT_ASSERT(isdigit('9'));
  CT_ASSERT(!isdigit('\000'));
  CT_ASSERT(isxdigit('A'));
  CT_ASSERT(isxdigit('a'));
  CT_ASSERT(!isxdigit('h'));
  CT_ASSERT(isxdigit('9'));
  CT_ASSERT(!isxdigit('\000'));
  CT_ASSERT(isspace(' '));
  CT_ASSERT(!isspace('9'));
  CT_ASSERT(!isspace('\000'));
  CT_ASSERT(isalpha('A'));
  CT_ASSERT(isalpha('a'));
  CT_ASSERT(isalpha('h'));
  CT_ASSERT(!isalpha('9'));
  CT_ASSERT(!isalpha('\000'));
  CT_ASSERT(isprint(' '));
  CT_ASSERT(isprint('A'));
  CT_ASSERT(isprint('a'));
  CT_ASSERT(isprint('h'));
  CT_ASSERT(isprint('9'));
  CT_ASSERT(!isprint('\000'));
  CT_ASSERT(!isgraph(' '));
  CT_ASSERT(isgraph('A'));
  CT_ASSERT(isgraph('a'));
  CT_ASSERT(isgraph('h'));
  CT_ASSERT(isgraph('9'));
  CT_ASSERT(!isgraph('\000'));
  CT_ASSERT(toupper('c') == 'C');
  CT_ASSERT(toupper('C') == 'C');
  CT_ASSERT(toupper('9') == '9');
  CT_ASSERT(tolower('c') == 'c');
  CT_ASSERT(tolower('C') == 'c');
  CT_ASSERT(tolower('9') == '9');
  ;
}
```