user: Translate the below assembly code into C programming language:

```asm
<BASM_XCallSplitSigW64>:
  endbr64
  push   %r12
  mov    %rsi,%r11
  mov    %rdx,%r10
  mov    %rcx,%r9
  push   %rbp
  push   %rbx
  movzbl (%rdi),%eax
  cmp    $0x28,%al
  jne    L96
  movzbl 0x1(%rdi),%eax
  add    $0x1,%rdi
L96:
  xor    %r8d,%r8d
  xor    %ecx,%ecx
  xor    %r12d,%r12d
  test   %al,%al
  je     L121
  cmp    $0x29,%al
  je     L121
  lea    D23(%rip),%rsi
  lea    D7(%rip),%rbp
  lea    D5(%rip),%rbx
  nopl   (%rax)
L140:
  sub    $0x43,%eax
  lea    0x1(%rdi),%rdx
  cmp    $0x36,%al
  ja     L28
  movzbl %al,%eax
  movslq (%rsi,%rax,4),%rax
  add    %rsi,%rax
  notrack jmp *%rax
  cmp    $0x3,%ecx
  jle    L229
  add    $0x1,%r8d
  mov    %rdx,%rdi
L6:
  movzbl (%rdi),%eax
  test   %al,%al
  je     L121
  cmp    $0x29,%al
  jne    L140
L121:
  cmp    $0x29,%al
  sete   %al
  movzbl %al,%eax
  add    %rax,%rdi
  test   %r11,%r11
  je     L150
  mov    %rdi,(%r11)
L150:
  test   %r10,%r10
  je     L179
  mov    %ecx,(%r10)
L179:
  test   %r9,%r9
  je     L135
  mov    %r8d,(%r9)
L135:
  mov    %r12d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  ret
  cs nopw 0x0(%rax,%rax,1)
L28:
  mov    %rdx,%rdi
  jmp    L6
  nopl   (%rax)
  cmp    $0x3,%ecx
  jle    L229
  mov    %r8d,%eax
  mov    %rdx,%rdi
  and    $0x1,%eax
  lea    0x2(%r8,%rax,1),%r8d
  jmp    L6
  nopl   0x0(%rax)
  cmp    $0x3,%ecx
  jle    L87
  add    $0x1,%r8d
L130:
  movzbl 0x1(%rdi),%eax
  cmp    $0x50,%al
  jne    L252
  nopl   (%rax)
L335:
  movzbl 0x1(%rdx),%eax
  add    $0x1,%rdx
  cmp    $0x50,%al
  je     L335
L252:
  lea    -0x61(%rax),%edi
  cmp    $0x19,%dil
  ja     L151
  lea    0x1(%rdx),%rdi
  jmp    L6
  nopw   0x0(%rax,%rax,1)
  movzbl 0x1(%rdi),%eax
  lea    0x2(%rdi),%rdx
  sub    $0x64,%eax
  cmp    $0x7,%al
  ja     L28
  movzbl %al,%eax
  movslq 0x0(%rbp,%rax,4),%rax
  add    %rbp,%rax
  notrack jmp *%rax
  nopl   (%rax)
  movzbl 0x1(%rdi),%eax
  lea    0x2(%rdi),%rdx
  sub    $0x64,%eax
  cmp    $0x7,%al
  ja     L28
  movzbl %al,%eax
  movslq (%rbx,%rax,4),%rax
  add    %rbx,%rax
  notrack jmp *%rax
  nopl   0x0(%rax,%rax,1)
L229:
  add    $0x1,%ecx
  mov    %rdx,%rdi
  jmp    L6
  nopl   0x0(%rax,%rax,1)
L87:
  add    $0x1,%ecx
  jmp    L130
  nopl   0x0(%rax,%rax,1)
  add    $0x4,%r12d
  mov    %rdx,%rdi
  jmp    L6
  nopl   0x0(%rax)
  add    $0x20,%r12d
  mov    %rdx,%rdi
  jmp    L6
  nopl   0x0(%rax)
  add    $0x10,%r12d
  mov    %rdx,%rdi
  jmp    L6
  nopl   0x0(%rax)
  add    $0x8,%r12d
  mov    %rdx,%rdi
  jmp    L6
  nopl   0x0(%rax)
L151:
  mov    %rdx,%rdi
  cmp    $0x58,%al
  jne    L6
  movzbl (%rdx),%eax
  cmp    $0x3b,%al
  je     L114
  test   %al,%al
  jne    L227
  jmp    L114
  nopl   0x0(%rax,%rax,1)
L95:
  cmp    $0x3b,%al
  je     L114
L227:
  movzbl 0x1(%rdx),%eax
  add    $0x1,%rdx
  test   %al,%al
  jne    L95
L114:
  xor    %edi,%edi
  cmp    $0x3b,%al
  sete   %dil
  add    %rdx,%rdi
  jmp    L6
  add    $0xc,%r12d
  mov    %rdx,%rdi
  jmp    L6
```

assistant: ```c
int BASM_XCallSplitSigW64(char *sig, char **esig, int *rni, int *rns) {
  char *s;
  int i, j, ni, ns;
  s = sig;
  i = 0;
  ni = 0;
  ns = 0;
  if (*s == '(')
    s++;
  while (*s && (*s != ')')) {
    switch (*s++) {
    case 'a':
    case 'b':
    case 'c':
    case 'h':
    case 's':
    case 't':
    case 'w':
    case 'i':
    case 'j':
      if (ni < 4) {
        ni++;
        break;
      }
      ns++;
      break;
    case 'l':
    case 'm':
    case 'x':
    case 'y':
      if (ni < 4) {
        ni++;
        break;
      }
      ns++;
      break;
    case 'r':
      if (ni < 4) {
        ni++;
        break;
      }
      ns++;
      break;
    case 'P':
      if (ni < 4)
        ni++;
      else
        ns++;
      while (*s == 'P')
        s++;
      if ((*s >= 'a') && (*s <= 'z')) {
        s++;
        break;
      }
      if (*s == 'X') {
        while (*s && *s != ';')
          s++;
        if (*s == ';')
          s++;
      }
      break;
    case 'd':
      if (ni < 4) {
        ni++;
        break;
      }
      ns++;
      break;
    case 'e':
      if (ni < 4) {
        ni++;
        break;
      }
      if (ns & 1)
        ns++;
      ns += 2;
      break;
    case 'f':
    case 'k':
      if (ni < 4) {
        ni++;
        break;
      }
      ns++;
      break;
    case 'g':
    case 'n':
    case 'o':
      if (ni < 4) {
        ni++;
        break;
      }
      if (ns & 1)
        ns++;
      ns += 2;
      break;
    case 'C':
      switch (*s++) {
      case 'f':
        i += 8;
        break;
      case 'd':
        i += 16;
        break;
      case 'e':
        i += 32;
        break;
      case 'g':
        i += 32;
        break;
      case 'k':
        i += 4;
        break;
      }
      break;
    case 'G':
      switch (*s++) {
      case 'f':
        i += 4;
        break;
      case 'd':
        i += 8;
        break;
      case 'e':
        i += 12;
        break;
      case 'g':
        i += 16;
        break;
      case 'k':
        i += 4;
        break;
      }
      break;
    default:
      break;
    }
  }
  if (*s && *s == ')')
    s++;
  if (esig)
    *esig = s;
  if (rni)
    *rni = ni;
  if (rns)
    *rns = ns;
  return (i);
}
```