user: Please show me the C implementation that matches the assembly code listed below:

```asm
<csc_memdump_line>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0xb0,%rsp
  mov    %rdi,-0x98(%rbp)
  mov    %esi,-0x9c(%rbp)
  mov    %edx,-0xa0(%rbp)
  mov    %rcx,-0xa8(%rbp)
  mov    %r8d,-0xac(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0xa0(%rbp),%eax
  mov    %eax,%edi
  call   <csc_memdump_find_step@plt>
  mov    %eax,-0x7c(%rbp)
  lea    -0x70(%rbp),%rax
  lea    D172(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcpy@plt>
  mov    -0xa0(%rbp),%eax
  and    $0x10000,%eax
  test   %eax,%eax
  je     L636
  lea    -0x70(%rbp),%rax
  lea    D51(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
L636:
  mov    -0xa0(%rbp),%eax
  sar    $0x8,%eax
  and    $0xf,%eax
  mov    %eax,-0x88(%rbp)
  cmpl   $0x0,-0x88(%rbp)
  jle    L78
  mov    -0xa0(%rbp),%eax
  and    $0x4000,%eax
  test   %eax,%eax
  je     L665
  mov    -0x88(%rbp),%eax
  movzbl %al,%edx
  lea    -0x50(%rbp),%rax
  lea    D162(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  jmp    L128
L665:
  mov    -0x88(%rbp),%eax
  movzbl %al,%edx
  lea    -0x50(%rbp),%rax
  lea    D39(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  jmp    L128
L78:
  mov    -0xa0(%rbp),%eax
  and    $0x4000,%eax
  test   %eax,%eax
  je     L440
  lea    -0x50(%rbp),%rax
  lea    D138(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcpy@plt>
  jmp    L128
L440:
  mov    -0xa0(%rbp),%eax
  and    $0xf0,%eax
  cmp    $0x10,%eax
  je     L162
  mov    -0xa0(%rbp),%eax
  and    $0xf0,%eax
  test   %eax,%eax
  jne    L237
L162:
  mov    -0x7c(%rbp),%eax
  add    %eax,%eax
  movzbl %al,%edx
  lea    -0x50(%rbp),%rax
  lea    D39(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  jmp    L128
L237:
  mov    -0xa0(%rbp),%eax
  and    $0xf0,%eax
  cmp    $0x40,%eax
  jne    L490
  mov    -0x7c(%rbp),%eax
  mov    %eax,%edx
  mov    %edx,%eax
  add    %eax,%eax
  add    %edx,%eax
  movzbl %al,%edx
  lea    -0x50(%rbp),%rax
  lea    D39(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  jmp    L128
L490:
  lea    -0x50(%rbp),%rax
  lea    D138(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcpy@plt>
L128:
  lea    -0x50(%rbp),%rdx
  lea    -0x70(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
  mov    -0xa0(%rbp),%eax
  and    $0xf,%eax
  cmp    $0x3,%eax
  jne    L355
  lea    -0x70(%rbp),%rax
  lea    D73(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
L355:
  mov    -0xa0(%rbp),%eax
  and    $0xf0,%eax
  cmp    $0x40,%eax
  je     L676
  cmp    $0x40,%eax
  jg     L320
  cmp    $0x30,%eax
  je     L455
  cmp    $0x30,%eax
  jg     L320
  cmp    $0x10,%eax
  je     L379
  cmp    $0x20,%eax
  je     L648
  jmp    L320
L379:
  lea    -0x70(%rbp),%rax
  lea    D197(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
  jmp    L181
L648:
  lea    -0x70(%rbp),%rax
  lea    D118(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
  jmp    L181
L455:
  lea    -0x70(%rbp),%rax
  lea    D177(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
  jmp    L181
L676:
  lea    -0x70(%rbp),%rax
  lea    D201(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
  jmp    L181
L320:
  mov    -0xa0(%rbp),%eax
  and    $0xf,%eax
  cmp    $0x4,%eax
  jne    L22
  lea    -0x70(%rbp),%rax
  lea    D84(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
  jmp    L181
L22:
  mov    -0xa0(%rbp),%eax
  and    $0xf,%eax
  cmp    $0x5,%eax
  jne    L655
  lea    -0x70(%rbp),%rax
  lea    D56(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
  jmp    L181
L655:
  lea    -0x70(%rbp),%rax
  lea    D174(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
  nop
L181:
  mov    -0xa0(%rbp),%eax
  and    $0x8000,%eax
  test   %eax,%eax
  jne    L315
  lea    -0x70(%rbp),%rax
  lea    D152(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcat@plt>
L315:
  movl   $0x0,-0x80(%rbp)
  mov    -0xa0(%rbp),%eax
  and    $0x2000,%eax
  test   %eax,%eax
  jne    L654
  mov    -0x98(%rbp),%rax
  movzbl %al,%edx
  lea    -0x50(%rbp),%rax
  lea    D113(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  cmpq   $0x0,-0xa8(%rbp)
  je     L614
  mov    -0xac(%rbp),%eax
  cmp    -0x88(%rbp),%eax
  jle    L614
  lea    -0x50(%rbp),%rdx
  mov    -0xa8(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcpy@plt>
  mov    -0x88(%rbp),%eax
  cltq
  add    %rax,-0xa8(%rbp)
  mov    -0x88(%rbp),%eax
  sub    %eax,-0xac(%rbp)
L614:
  mov    -0x88(%rbp),%eax
  add    %eax,-0x80(%rbp)
L654:
  mov    -0x98(%rbp),%rax
  mov    %rax,-0x78(%rbp)
  mov    -0x9c(%rbp),%eax
  mov    %eax,-0x84(%rbp)
  jmp    L589
L174:
  mov    -0xa0(%rbp),%eax
  and    $0xf,%eax
  cmp    $0x5,%eax
  ja     L327
  mov    %eax,%eax
  lea    0x0(,%rax,4),%rdx
  lea    D146(%rip),%rax
  mov    (%rdx,%rax,1),%eax
  cltq
  lea    D146(%rip),%rdx
  add    %rdx,%rax
  notrack jmp *%rax
  mov    -0xa0(%rbp),%eax
  and    $0xf0,%eax
  cmp    $0x30,%eax
  jne    L438
  mov    -0x78(%rbp),%rax
  movzwl (%rax),%eax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  jmp    L298
L438:
  mov    -0x78(%rbp),%rax
  movzwl (%rax),%eax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  jmp    L298
  mov    -0xa0(%rbp),%eax
  and    $0xf0,%eax
  cmp    $0x30,%eax
  jne    L191
  mov    -0x78(%rbp),%rax
  mov    (%rax),%eax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  jmp    L298
L191:
  mov    -0x78(%rbp),%rax
  mov    (%rax),%eax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  jmp    L298
  mov    -0xa0(%rbp),%eax
  and    $0xf0,%eax
  cmp    $0x30,%eax
  jne    L554
  mov    -0x78(%rbp),%rax
  mov    (%rax),%rax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  jmp    L298
L554:
  mov    -0x78(%rbp),%rax
  mov    (%rax),%rax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  jmp    L298
  mov    -0x78(%rbp),%rax
  movss  (%rax),%xmm0
  cvttss2si %xmm0,%eax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  jmp    L298
  mov    -0x78(%rbp),%rax
  movsd  (%rax),%xmm0
  cvttsd2si %xmm0,%eax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  jmp    L298
L327:
  mov    -0xa0(%rbp),%eax
  and    $0xf0,%eax
  cmp    $0x30,%eax
  jne    L361
  mov    -0x78(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
  jmp    L4
L361:
  mov    -0x78(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    %eax,-0x88(%rbp)
L4:
  nop
L298:
  cmpq   $0x0,-0xa8(%rbp)
  je     L140
  mov    -0xac(%rbp),%eax
  cmp    -0x88(%rbp),%eax
  jl     L140
  lea    -0x50(%rbp),%rdx
  mov    -0xa8(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcpy@plt>
  mov    -0x88(%rbp),%eax
  cltq
  add    %rax,-0xa8(%rbp)
  mov    -0x88(%rbp),%eax
  sub    %eax,-0xac(%rbp)
L140:
  mov    -0x88(%rbp),%eax
  add    %eax,-0x80(%rbp)
  mov    -0xa0(%rbp),%eax
  and    $0x20000,%eax
  test   %eax,%eax
  je     L409
  mov    -0x7c(%rbp),%eax
  cltq
  neg    %rax
  add    %rax,-0x78(%rbp)
  jmp    L387
L409:
  mov    -0x7c(%rbp),%eax
  cltq
  add    %rax,-0x78(%rbp)
L387:
  mov    -0x7c(%rbp),%eax
  sub    %eax,-0x84(%rbp)
L589:
  mov    -0x84(%rbp),%eax
  cmp    -0x7c(%rbp),%eax
  jge    L174
  mov    -0xa0(%rbp),%eax
  and    $0x1000,%eax
  test   %eax,%eax
  je     L414
  mov    -0x80(%rbp),%eax
  jmp    L383
L414:
  cmpq   $0x0,-0xa8(%rbp)
  je     L46
  cmpl   $0x0,-0xac(%rbp)
  jle    L46
  mov    -0xa8(%rbp),%rax
  lea    D152(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcpy@plt>
  addq   $0x1,-0xa8(%rbp)
  subl   $0x1,-0xac(%rbp)
L46:
  addl   $0x1,-0x80(%rbp)
  mov    -0x98(%rbp),%rax
  mov    %rax,-0x78(%rbp)
  mov    -0x9c(%rbp),%eax
  mov    %eax,-0x84(%rbp)
  jmp    L202
L510:
  cmpq   $0x0,-0xa8(%rbp)
  je     L317
  cmpl   $0x0,-0xac(%rbp)
  jle    L317
  mov    -0x78(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x1f,%al
  jle    L53
  mov    -0x78(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x7f,%al
  jne    L647
L53:
  mov    -0xa8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0xa8(%rbp)
  movb   $0x2e,(%rax)
  jmp    L408
L647:
  mov    -0xa8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0xa8(%rbp)
  mov    -0x78(%rbp),%rdx
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
L408:
  subl   $0x1,-0xac(%rbp)
L317:
  mov    -0xa0(%rbp),%eax
  and    $0x20000,%eax
  test   %eax,%eax
  je     L662
  subq   $0x1,-0x78(%rbp)
  jmp    L513
L662:
  addq   $0x1,-0x78(%rbp)
L513:
  subl   $0x1,-0x84(%rbp)
  addl   $0x1,-0x80(%rbp)
L202:
  cmpl   $0x0,-0x84(%rbp)
  jne    L510
  cmpq   $0x0,-0xa8(%rbp)
  je     L586
  cmpl   $0x0,-0xac(%rbp)
  jle    L586
  mov    -0xa8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0xa8(%rbp)
  movb   $0x0,(%rax)
L586:
  mov    -0x80(%rbp),%eax
L383:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L129
  call   <__stack_chk_fail@plt>
L129:
  leave
  ret
```

tool_calls: name: read_data
arguments: data_label: D172
type: string
name: read_data
arguments: data_label: D51
type: string
name: read_data
arguments: data_label: D162
type: string
name: read_data
arguments: data_label: D39
type: string
name: read_data
arguments: data_label: D138
type: string
name: read_data
arguments: data_label: D73
type: string
name: read_data
arguments: data_label: D197
type: string
name: read_data
arguments: data_label: D118
type: string
name: read_data
arguments: data_label: D177
type: string
name: read_data
arguments: data_label: D201
type: string
name: read_data
arguments: data_label: D84
type: string
name: read_data
arguments: data_label: D56
type: string
name: read_data
arguments: data_label: D174
type: string
name: read_data
arguments: data_label: D152
type: string
name: read_data
arguments: data_label: D113
type: string

tool: D172: %

tool: D51: -

tool: D162: %d

tool: D39: 0%d

tool: 

tool: D73: ll

tool: D197: x

tool: D118: u

tool: D177: d

tool: D201: o

tool: D84: f

tool: D56: e

tool: D174: X

tool: D152:  

tool: D113: %lX: 

assistant: ```c
int csc_memdump_line(void *mem, int msize, int flags, char *buf, int blen) {
  char *mp, format[32], tmp[64];
  int n, sp, step, amnt;
  step = csc_memdump_find_step(flags);
  strcpy(format, "%");
  if (flags & 0x10000) {
    strcat(format, "-");
  }
  n = (flags & 0xf00) >> 8;
  if (n > 0) {
    if (flags & 0x4000) {
      sprintf(tmp, "%d", n);
    } else {
      sprintf(tmp, "0%d", n);
    }
  } else if (flags & 0x4000) {
    strcpy(tmp, "");
  } else if (((((flags)&0xf0) == 0x10) || (((flags)&0xf0) == 0))) {
    sprintf(tmp, "0%d", step * 2);
  } else if ((flags & 0xf0) == 0x40) {
    sprintf(tmp, "0%d", step * 3);
  } else {
    strcpy(tmp, "");
  }
  strcat(format, tmp);
  if ((flags & 0xf) == 3) {
    strcat(format, "ll");
  }
  switch (flags & 0xf0) {
  case 0x10:
    strcat(format, "x");
    break;
  case 0x20:
    strcat(format, "u");
    break;
  case 0x30:
    strcat(format, "d");
    break;
  case 0x40:
    strcat(format, "o");
    break;
  default:
    if ((flags & 0xf) == 4) {
      strcat(format, "f");
      break;
    }
    if ((flags & 0xf) == 5) {
      strcat(format, "e");
      break;
    }
    strcat(format, "X");
    break;
  }
  if ((flags & 0x8000) == 0) {
    strcat(format, " ");
  }
  amnt = 0;
  if ((flags & 0x2000) == 0) {
    n = sprintf(tmp, "%lX: ", (unsigned long)mem);
    if (buf && (blen > n)) {
      strcpy(buf, tmp);
      buf += n;
      blen -= n;
    }
    amnt += n;
  }
  mp = mem;
  sp = msize;
  while (sp >= step) {
    switch (flags & 0xf) {
    case 1:
      if ((((flags)&0xf0) == 0x30)) {
        n = sprintf(tmp, format, *((short *)mp));
      } else {
        n = sprintf(tmp, format, *((unsigned short *)mp));
      }
      break;
    case 2:
      if ((((flags)&0xf0) == 0x30)) {
        n = sprintf(tmp, format, *((int *)mp));
      } else {
        n = sprintf(tmp, format, *((unsigned *)mp));
      }
      break;
    case 3:
      if ((((flags)&0xf0) == 0x30)) {
        n = sprintf(tmp, format, *((long long *)mp));
      } else {
        n = sprintf(tmp, format, *((unsigned long long *)mp));
      }
      break;
    case 4:
      n = sprintf(tmp, format, *((float *)mp));
      break;
    case 5:
      n = sprintf(tmp, format, *((double *)mp));
      break;
    default:
      if ((((flags)&0xf0) == 0x30)) {
        n = sprintf(tmp, format, *mp);
      } else {
        n = sprintf(tmp, format, *((unsigned char *)mp));
      }
      break;
    }
    if (buf && blen >= n) {
      strcpy(buf, tmp);
      buf += n;
      blen -= n;
    }
    amnt += n;
    if (flags & 0x20000) {
      mp -= step;
    } else {
      mp += step;
    }
    sp -= step;
  }
  if (flags & 0x1000) {
    return amnt;
  }
  if (buf && blen > 0) {
    strcpy(buf, " ");
    buf++;
    blen--;
  }
  amnt++;
  mp = mem;
  sp = msize;
  while (sp) {
    if (buf && blen > 0) {
      if ((*mp < ' ') || (*mp > 0x7e)) {
        *buf++ = '.';
      } else {
        *buf++ = *mp;
      }
      blen--;
    }
    if (flags & 0x20000) {
      mp--;
    } else {
      mp++;
    }
    sp--;
    amnt++;
  }
  if (buf && blen > 0) {
    *buf++ = 0;
  }
  return amnt;
}
```