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

```asm
<pack_nametable>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %esi,-0x3c(%rbp)
  mov    %edx,-0x40(%rbp)
  mov    %ecx,-0x44(%rbp)
  mov    %r8d,-0x48(%rbp)
  mov    %r9,-0x50(%rbp)
  movl   $0x0,-0x28(%rbp)
  movl   $0x0,-0x24(%rbp)
  movl   $0x0,-0x20(%rbp)
  movl   $0x0,-0x1c(%rbp)
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <assert@plt>
  mov    -0x50(%rbp),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <assert@plt>
  mov    0x10(%rbp),%rdi
  mov    $0x0,%eax
  call   <assert@plt>
  mov    -0x50(%rbp),%rax
  movq   $0x0,(%rax)
  jmp    L344
L22:
  movl   $0x0,-0x10(%rbp)
  movl   $0x0,-0xc(%rbp)
  movl   $0x0,-0x8(%rbp)
  mov    -0x20(%rbp),%eax
  shl    $0x5,%eax
  mov    %eax,%edx
  mov    -0x44(%rbp),%eax
  add    %edx,%eax
  mov    %eax,-0x4(%rbp)
  jmp    L41
L124:
  mov    -0x1c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  mov    %al,-0x29(%rbp)
  cmpl   $0x3,-0xc(%rbp)
  je     L141
  cmpl   $0x3,-0xc(%rbp)
  jg     L41
  cmpl   $0x2,-0xc(%rbp)
  je     L309
  cmpl   $0x2,-0xc(%rbp)
  jg     L41
  cmpl   $0x0,-0xc(%rbp)
  je     L371
  cmpl   $0x1,-0xc(%rbp)
  je     L366
  jmp    L41
L371:
  mov    -0x10(%rbp),%eax
  add    $0x3,%eax
  cmp    %eax,-0x40(%rbp)
  jle    L96
  mov    -0x1c(%rbp),%eax
  cltq
  lea    0x1(%rax),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    %al,-0x29(%rbp)
  jne    L96
  mov    -0x1c(%rbp),%eax
  cltq
  lea    0x2(%rax),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    %al,-0x29(%rbp)
  jne    L96
  mov    -0x1c(%rbp),%eax
  cltq
  lea    0x3(%rax),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    %al,-0x29(%rbp)
  jne    L96
  mov    $0x1,%eax
  jmp    L434
L96:
  mov    $0x0,%eax
L434:
  mov    %eax,-0x8(%rbp)
L366:
  cmpb   $0x0,-0x29(%rbp)
  jne    L224
  movl   $0x0,-0x8(%rbp)
  addl   $0x1,-0x1c(%rbp)
  addl   $0x1,-0x10(%rbp)
  addl   $0x1,-0x4(%rbp)
  jmp    L41
L224:
  mov    -0x28(%rbp),%eax
  add    $0x2,%eax
  cmp    %eax,-0x24(%rbp)
  jg     L210
  addl   $0x40,-0x24(%rbp)
  mov    -0x24(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <realloc@plt>
  mov    -0x50(%rbp),%rdx
  mov    %rax,(%rdx)
L210:
  mov    -0x4(%rbp),%eax
  sar    $0x8,%eax
  mov    %eax,%esi
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  add    %rcx,%rax
  mov    %esi,%edx
  mov    %dl,(%rax)
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  add    %rcx,%rax
  mov    -0x4(%rbp),%edx
  mov    %dl,(%rax)
  cmpl   $0x0,-0x8(%rbp)
  je     L86
  movl   $0x4,-0x18(%rbp)
  movzbl -0x29(%rbp),%eax
  mov    %al,-0x2a(%rbp)
  addl   $0x4,-0x1c(%rbp)
  addl   $0x4,-0x10(%rbp)
  movl   $0x2,-0xc(%rbp)
  jmp    L41
L86:
  mov    -0x28(%rbp),%eax
  mov    %eax,-0x14(%rbp)
  mov    -0x28(%rbp),%eax
  add    $0x2,%eax
  cmp    %eax,-0x24(%rbp)
  jg     L99
  addl   $0x40,-0x24(%rbp)
  mov    -0x24(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <realloc@plt>
  mov    -0x50(%rbp),%rdx
  mov    %rax,(%rdx)
L99:
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  add    %rcx,%rax
  movb   $0x0,(%rax)
  movl   $0x1,-0x18(%rbp)
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  lea    (%rcx,%rax,1),%rdx
  movzbl -0x29(%rbp),%eax
  mov    %al,(%rdx)
  addl   $0x1,-0x1c(%rbp)
  addl   $0x1,-0x10(%rbp)
  movl   $0x3,-0xc(%rbp)
  jmp    L41
L309:
  movzbl -0x29(%rbp),%eax
  cmp    -0x2a(%rbp),%al
  jne    L7
  addl   $0x1,-0x18(%rbp)
  addl   $0x1,-0x1c(%rbp)
  addl   $0x1,-0x10(%rbp)
L7:
  movzbl -0x29(%rbp),%eax
  cmp    -0x2a(%rbp),%al
  jne    L253
  cmpl   $0x3f,-0x18(%rbp)
  jne    L41
L253:
  mov    -0x28(%rbp),%eax
  add    $0x2,%eax
  cmp    %eax,-0x24(%rbp)
  jg     L418
  addl   $0x40,-0x24(%rbp)
  mov    -0x24(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <realloc@plt>
  mov    -0x50(%rbp),%rdx
  mov    %rax,(%rdx)
L418:
  mov    -0x18(%rbp),%eax
  or     $0x40,%eax
  mov    %eax,%esi
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  add    %rcx,%rax
  mov    %esi,%edx
  mov    %dl,(%rax)
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  lea    (%rcx,%rax,1),%rdx
  movzbl -0x2a(%rbp),%eax
  mov    %al,(%rdx)
  mov    -0x18(%rbp),%eax
  add    %eax,-0x4(%rbp)
  movl   $0x0,-0xc(%rbp)
  jmp    L41
L141:
  mov    -0x10(%rbp),%eax
  add    $0x3,%eax
  cmp    %eax,-0x40(%rbp)
  jle    L195
  mov    -0x1c(%rbp),%eax
  cltq
  lea    0x1(%rax),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    %al,-0x29(%rbp)
  jne    L195
  mov    -0x1c(%rbp),%eax
  cltq
  lea    0x2(%rax),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    %al,-0x29(%rbp)
  jne    L195
  mov    -0x1c(%rbp),%eax
  cltq
  lea    0x3(%rax),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    %al,-0x29(%rbp)
  jne    L195
  mov    $0x1,%eax
  jmp    L307
L195:
  mov    $0x0,%eax
L307:
  mov    %eax,-0x8(%rbp)
  cmpl   $0x0,-0x8(%rbp)
  je     L294
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x14(%rbp),%eax
  cltq
  add    %rdx,%rax
  mov    -0x18(%rbp),%edx
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%eax
  add    %eax,-0x4(%rbp)
  movl   $0x1,-0xc(%rbp)
  jmp    L416
L294:
  mov    -0x28(%rbp),%eax
  add    $0x1,%eax
  cmp    %eax,-0x24(%rbp)
  jg     L128
  addl   $0x40,-0x24(%rbp)
  mov    -0x24(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <realloc@plt>
  mov    -0x50(%rbp),%rdx
  mov    %rax,(%rdx)
L128:
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  lea    (%rcx,%rax,1),%rdx
  movzbl -0x29(%rbp),%eax
  mov    %al,(%rdx)
  addl   $0x1,-0x1c(%rbp)
  addl   $0x1,-0x10(%rbp)
  addl   $0x1,-0x18(%rbp)
  cmpl   $0x3f,-0x18(%rbp)
  jne    L416
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x14(%rbp),%eax
  cltq
  add    %rdx,%rax
  mov    -0x18(%rbp),%edx
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%eax
  add    %eax,-0x4(%rbp)
  movl   $0x1,-0xc(%rbp)
L416:
  nop
L41:
  mov    -0x10(%rbp),%eax
  cmp    -0x40(%rbp),%eax
  jl     L124
  cmpl   $0x3,-0xc(%rbp)
  je     L167
  cmpl   $0x3,-0xc(%rbp)
  jg     L179
  cmpl   $0x1,-0xc(%rbp)
  jg     L16
  cmpl   $0x0,-0xc(%rbp)
  jmp    L179
L16:
  cmpl   $0x2,-0xc(%rbp)
  jne    L179
  mov    -0x28(%rbp),%eax
  add    $0x2,%eax
  cmp    %eax,-0x24(%rbp)
  jg     L185
  addl   $0x40,-0x24(%rbp)
  mov    -0x24(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <realloc@plt>
  mov    -0x50(%rbp),%rdx
  mov    %rax,(%rdx)
L185:
  mov    -0x18(%rbp),%eax
  or     $0x40,%eax
  mov    %eax,%esi
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  add    %rcx,%rax
  mov    %esi,%edx
  mov    %dl,(%rax)
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  lea    (%rcx,%rax,1),%rdx
  movzbl -0x2a(%rbp),%eax
  mov    %al,(%rdx)
  jmp    L179
L167:
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x14(%rbp),%eax
  cltq
  add    %rdx,%rax
  mov    -0x18(%rbp),%edx
  mov    %dl,(%rax)
  nop
L179:
  addl   $0x1,-0x20(%rbp)
L344:
  mov    -0x20(%rbp),%eax
  imul   -0x40(%rbp),%eax
  cmp    %eax,-0x3c(%rbp)
  jg     L22
  cmpl   $0x0,-0x48(%rbp)
  je     L291
  mov    -0x28(%rbp),%eax
  add    $0x1,%eax
  cmp    %eax,-0x24(%rbp)
  jg     L163
  addl   $0x1,-0x24(%rbp)
  mov    -0x24(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <realloc@plt>
  mov    -0x50(%rbp),%rdx
  mov    %rax,(%rdx)
L163:
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x28(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x28(%rbp)
  cltq
  add    %rcx,%rax
  movb   $0x0,(%rax)
L291:
  mov    0x10(%rbp),%rax
  mov    -0x28(%rbp),%edx
  mov    %edx,(%rax)
  nop
  leave
  ret
```

assistant: ```c
void pack_nametable(const unsigned char *nametable, int nametable_sz, int width, int vram_address, int zero_terminate, unsigned char **out, int *out_sz) {
  int out_pos = 0;
  int buf_sz = 0;
  int y = 0;
  int in_pos = 0;
  assert(nametable);
  assert(out);
  assert(out_sz);
  *out = 0;
  while (y * width < nametable_sz) {
    unsigned char rlech;
    int count;
    int count_pos;
    int x = 0;
    int state = 0;
    int start_rle = 0;
    int addr = vram_address + (y * 32);
    while (x < width) {
      const unsigned char ch = nametable[in_pos];
      switch (state) {
      case 0:
        start_rle = (x + 4 <= width) && (nametable[in_pos + 1] == ch) && (nametable[in_pos + 2] == ch) && (nametable[in_pos + 3] == ch);
      case 1:
        if (ch == 0) {
          start_rle = 0;
          ++in_pos;
          ++x;
          ++addr;
          break;
        }
        if (out_pos + 2 >= buf_sz) {
          buf_sz += 64;
          *out = (unsigned char *)realloc(*out, buf_sz);
        }
        (*out)[out_pos++] = (unsigned char)(addr >> 8);
        (*out)[out_pos++] = (unsigned char)(addr & 255);
        if (start_rle) {
          count = 4;
          rlech = ch;
          in_pos += 4;
          x += 4;
          state = 2;
        } else {
          count_pos = out_pos;
          if (out_pos + 2 >= buf_sz) {
            buf_sz += 64;
            *out = (unsigned char *)realloc(*out, buf_sz);
          }
          (*out)[out_pos++] = 0;
          count = 1;
          (*out)[out_pos++] = ch;
          ++in_pos;
          ++x;
          state = 3;
        }
        break;
      case 2:
        if (ch == rlech) {
          ++count;
          ++in_pos;
          ++x;
        }
        if ((ch != rlech) || (count == 0x3F)) {
          if (out_pos + 2 >= buf_sz) {
            buf_sz += 64;
            *out = (unsigned char *)realloc(*out, buf_sz);
          }
          (*out)[out_pos++] = (unsigned char)(0x40 | count);
          (*out)[out_pos++] = rlech;
          addr += count;
          state = 0;
        }
        break;
      case 3:
        start_rle = ((x + 4 <= width) && (nametable[in_pos + 1] == ch) && (nametable[in_pos + 2] == ch) && (nametable[in_pos + 3] == ch));
        if (start_rle) {
          (*out)[count_pos] = count;
          addr += count;
          state = 1;
        } else {
          if (out_pos + 1 >= buf_sz) {
            buf_sz += 64;
            *out = (unsigned char *)realloc(*out, buf_sz);
          }
          (*out)[out_pos++] = ch;
          ++in_pos;
          ++x;
          ++count;
          if (count == 0x3F) {
            (*out)[count_pos] = count;
            addr += count;
            state = 1;
          }
        }
        break;
      }
    }
    switch (state) {
    case 0:
    case 1:
      break;
    case 2:
      if (out_pos + 2 >= buf_sz) {
        buf_sz += 64;
        *out = (unsigned char *)realloc(*out, buf_sz);
      }
      (*out)[out_pos++] = (unsigned char)(0x40 | count);
      (*out)[out_pos++] = rlech;
      break;
    case 3:
      (*out)[count_pos] = count;
      break;
    }
    ++y;
  }
  if (zero_terminate) {
    if (out_pos + 1 >= buf_sz) {
      buf_sz += 1;
      *out = (unsigned char *)realloc(*out, buf_sz);
    }
    (*out)[out_pos++] = 0;
  }
  *out_sz = out_pos;
}
```