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

```asm
<disp_num>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x48(%rbp)
  mov    %esi,-0x4c(%rbp)
  mov    %edx,-0x50(%rbp)
  mov    %ecx,-0x54(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0x50(%rbp),%eax
  mov    %eax,-0x38(%rbp)
  mov    -0x48(%rbp),%rax
  shr    $0x3f,%rax
  movzbl %al,%eax
  mov    %eax,-0x34(%rbp)
  cmpl   $0x0,-0x34(%rbp)
  je     L92
  mov    -0x48(%rbp),%rax
  neg    %rax
  jmp    L23
L92:
  mov    -0x48(%rbp),%rax
L23:
  mov    %rax,-0x28(%rbp)
  lea    -0x20(%rbp),%rax
  add    $0x10,%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x30(%rbp),%rax
  movb   $0x0,(%rax)
L6:
  mov    -0x28(%rbp),%rcx
  movabs $0x6666666666666667,%rdx
  mov    %rcx,%rax
  imul   %rdx
  mov    %rdx,%rax
  sar    $0x2,%rax
  mov    %rcx,%rsi
  sar    $0x3f,%rsi
  sub    %rsi,%rax
  mov    %rax,%rdx
  mov    %rdx,%rax
  shl    $0x2,%rax
  add    %rdx,%rax
  add    %rax,%rax
  sub    %rax,%rcx
  mov    %rcx,%rdx
  mov    %edx,%eax
  add    $0x30,%eax
  subq   $0x1,-0x30(%rbp)
  mov    %eax,%edx
  mov    -0x30(%rbp),%rax
  mov    %dl,(%rax)
  subl   $0x1,-0x38(%rbp)
  mov    -0x50(%rbp),%eax
  sub    -0x38(%rbp),%eax
  cmp    %eax,-0x54(%rbp)
  jne    L7
  subq   $0x1,-0x30(%rbp)
  mov    -0x30(%rbp),%rax
  movb   $0x2e,(%rax)
  subl   $0x1,-0x38(%rbp)
  movl   $0x0,-0x54(%rbp)
L7:
  mov    -0x28(%rbp),%rcx
  movabs $0x6666666666666667,%rdx
  mov    %rcx,%rax
  imul   %rdx
  mov    %rdx,%rax
  sar    $0x2,%rax
  sar    $0x3f,%rcx
  mov    %rcx,%rdx
  sub    %rdx,%rax
  mov    %rax,-0x28(%rbp)
  cmpq   $0x0,-0x28(%rbp)
  jne    L6
  cmpl   $0x0,-0x54(%rbp)
  jne    L6
  cmpl   $0x0,-0x34(%rbp)
  je     L36
  subq   $0x1,-0x30(%rbp)
  mov    -0x30(%rbp),%rax
  movb   $0x2d,(%rax)
  subl   $0x1,-0x38(%rbp)
L36:
  cmpl   $0x0,-0x38(%rbp)
  jns    L79
  lea    -0x20(%rbp),%rax
  add    $0x10,%rax
  mov    %rax,-0x30(%rbp)
  movl   $0x0,-0x3c(%rbp)
  jmp    L86
L90:
  subq   $0x1,-0x30(%rbp)
  mov    -0x30(%rbp),%rax
  movb   $0x2a,(%rax)
  addl   $0x1,-0x3c(%rbp)
L86:
  mov    -0x3c(%rbp),%eax
  cmp    -0x50(%rbp),%eax
  jl     L90
  jmp    L79
L24:
  subq   $0x1,-0x30(%rbp)
  mov    -0x30(%rbp),%rax
  movb   $0x20,(%rax)
L79:
  mov    -0x38(%rbp),%eax
  lea    -0x1(%rax),%edx
  mov    %edx,-0x38(%rbp)
  test   %eax,%eax
  jg     L24
  mov    -0x4c(%rbp),%ecx
  mov    -0x30(%rbp),%rax
  mov    $0x0,%edx
  mov    %ecx,%esi
  mov    %rax,%rdi
  call   <disp_text@plt>
  nop
  mov    -0x8(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L107
  call   <__stack_chk_fail@plt>
L107:
  leave
  ret
```

assistant: ```c
void disp_num(long num, int position, int width, int nfrac) {
  char tempc[17];
  char *bufptr;
  int i, wcnt = width, neg = num < 0;
  long unum = neg ? -num : num;
  *(bufptr = &tempc[17 - 1]) = 0;
  do {
    *--bufptr = (unum % 10) + '0';
    wcnt--;
    if ((width - wcnt) == nfrac) {
      *--bufptr = '.';
      wcnt--;
      nfrac = 0;
    }
  } while ((unum /= 10) || nfrac);
  if (neg) {
    *--bufptr = '-';
    wcnt--;
  }
  if (wcnt < 0) {
    bufptr = &tempc[17 - 1];
    for (i = 0; i < width; i++) {
      *--bufptr = '*';
    }
  }
  while ((wcnt--) > 0) {
    *--bufptr = ' ';
  }
  disp_text(bufptr, position, 0);
}
```