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

```asm
<bmap2units>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x68,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x58(%rsp)
  xor    %eax,%eax
  mov    $0x1,%eax
  mov    $0x0,%ebp
  lea    D51(%rip),%r8
  mov    $0x1,%esi
  test   %edi,%edi
  jne    L14
  mov    $0x7f,%edx
  lea    D16(%rip),%rsi
  lea    D109(%rip),%rbx
  mov    %rbx,%rdi
  call   <strncpy2@plt>
  mov    %rbx,%rax
  jmp    L146
L53:
  add    $0x1,%rax
  cmp    $0x11,%rax
  je     L138
L14:
  mov    (%r8,%rax,4),%ecx
  mov    %esi,%edx
  shl    %cl,%edx
  test   %edi,%edx
  je     L53
  movslq %ebp,%rdx
  mov    %eax,(%rsp,%rdx,4)
  lea    0x1(%rbp),%ebp
  jmp    L53
L138:
  movslq %ebp,%rax
  movl   $0x0,(%rsp,%rax,4)
  movb   $0x0,D40(%rip)
  movb   $0x0,D109(%rip)
  mov    (%rsp),%esi
  lea    D40(%rip),%rax
  test   %ebp,%ebp
  jle    L146
  mov    $0x1,%ebx
  mov    $0x1,%eax
  lea    D109(%rip),%r13
  lea    D24(%rip),%r15
  lea    D25(%rip),%r14
  jmp    L54
L119:
  add    $0x1,%eax
  jmp    L95
L20:
  lea    0x50(%rsp),%rdi
  mov    %esi,%edx
  mov    %r15,%rsi
  mov    $0x0,%eax
  call   <sprintf@plt>
L148:
  mov    %r13,%rdi
  call   <strlen@plt>
  mov    $0x7f,%edx
  sub    %rax,%rdx
  lea    0x50(%rsp),%rsi
  mov    %r13,%rdi
  call   <strncat@plt>
  mov    %r12d,%esi
  mov    $0x1,%eax
L95:
  add    $0x1,%rbx
  cmp    %ebx,%ebp
  jl     L78
L54:
  mov    (%rsp,%rbx,4),%r12d
  mov    -0x4(%rsp,%rbx,4),%ecx
  lea    0x1(%rcx),%edx
  cmp    %edx,%r12d
  je     L119
  cmp    $0x1,%eax
  je     L20
  cmp    $0x2,%eax
  je     L122
  lea    0x50(%rsp),%rdi
  mov    %esi,%edx
  mov    %r14,%rsi
  mov    $0x0,%eax
  call   <sprintf@plt>
  jmp    L148
L122:
  lea    0x50(%rsp),%rdi
  mov    %esi,%edx
  lea    D88(%rip),%rsi
  mov    $0x0,%eax
  call   <sprintf@plt>
  jmp    L148
L78:
  lea    D40(%rip),%rax
L146:
  mov    0x58(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L133
  add    $0x68,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L133:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: read_data
arguments: data_tag: D51
type: string
name: read_data
arguments: data_tag: D16
type: string
name: read_data
arguments: data_tag: D24
type: string
name: read_data
arguments: data_tag: D25
type: string
name: read_data
arguments: data_tag: D88
type: string

tool: 

tool: D16: 0

tool: D24: ,%d

tool: D25: ,%d-%d

tool: D88: ,%d,%d

assistant: ```c
char *bmap2units(unsigned int bmap) {
  static int invmap[] = {6, 14, 2, 10, 1, 9, 5, 13, 7, 15, 3, 11, 0, 8, 4, 12};
  static char buffer[128];
  char minbuf[8];
  unsigned int mask = 0x01;
  int j, count, nunits;
  int units[17];
  int first;
  if (bmap == 0) {
    (int)strncpy2(buffer, "0", sizeof(buffer) - 1);
    return buffer;
  }
  nunits = 0;
  for (j = 0; j < 16; j++) {
    mask = 0x01 << invmap[j];
    if (bmap & mask) {
      units[nunits++] = j + 1;
    }
  }
  units[nunits++] = 0;
  buffer[0] = buffer[1] = '\0';
  first = units[0];
  count = 1;
  for (j = 1; j < nunits; j++) {
    if (units[j] == units[j - 1] + 1) {
      count++;
      continue;
    }
    switch (count) {
    case 1:
      sprintf(minbuf, ",%d", first);
      break;
    case 2:
      sprintf(minbuf, ",%d,%d", first, units[j - 1]);
      break;
    default:
      sprintf(minbuf, ",%d-%d", first, units[j - 1]);
      break;
    }
    (int)strncat(buffer, minbuf, sizeof(buffer) - 1 - strlen(buffer));
    first = units[j];
    count = 1;
  }
  return buffer + 1;
}
```