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

```asm
<davidegrayson_nibble_sort_counter_word>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  add    $0xffffffffffffff80,%rsp
  mov    %rdi,-0x78(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movq   $0x0,-0x20(%rbp)
  movq   $0x0,-0x18(%rbp)
  mov    -0x78(%rbp),%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x4,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x8,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0xc,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x10,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x14,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x18,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x1c,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x20,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x24,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x28,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x2c,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x30,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x34,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x38,%rax
  and    $0xf,%eax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  mov    -0x78(%rbp),%rax
  shr    $0x3c,%rax
  movzbl -0x20(%rbp,%rax,1),%edx
  add    $0x1,%edx
  mov    %dl,-0x20(%rbp,%rax,1)
  movq   $0x0,-0x28(%rbp)
  movl   $0x0,-0x64(%rbp)
  jmp    L199
L298:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0x1000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x64(%rbp)
L199:
  movzbl -0x1f(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x64(%rbp)
  jb     L298
  movl   $0x0,-0x60(%rbp)
  jmp    L216
L297:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0x2000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x60(%rbp)
L216:
  movzbl -0x1e(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x60(%rbp)
  jb     L297
  movl   $0x0,-0x5c(%rbp)
  jmp    L142
L11:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0x3000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x5c(%rbp)
L142:
  movzbl -0x1d(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x5c(%rbp)
  jb     L11
  movl   $0x0,-0x58(%rbp)
  jmp    L151
L1:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0x4000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x58(%rbp)
L151:
  movzbl -0x1c(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x58(%rbp)
  jb     L1
  movl   $0x0,-0x54(%rbp)
  jmp    L168
L80:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0x5000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x54(%rbp)
L168:
  movzbl -0x1b(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x54(%rbp)
  jb     L80
  movl   $0x0,-0x50(%rbp)
  jmp    L112
L122:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0x6000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x50(%rbp)
L112:
  movzbl -0x1a(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x50(%rbp)
  jb     L122
  movl   $0x0,-0x4c(%rbp)
  jmp    L97
L153:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0x7000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x4c(%rbp)
L97:
  movzbl -0x19(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x4c(%rbp)
  jb     L153
  movl   $0x0,-0x48(%rbp)
  jmp    L14
L280:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0x8000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x48(%rbp)
L14:
  movzbl -0x18(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x48(%rbp)
  jb     L280
  movl   $0x0,-0x44(%rbp)
  jmp    L48
L121:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0x9000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x44(%rbp)
L48:
  movzbl -0x17(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x44(%rbp)
  jb     L121
  movl   $0x0,-0x40(%rbp)
  jmp    L279
L79:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0xa000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x40(%rbp)
L279:
  movzbl -0x16(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x40(%rbp)
  jb     L79
  movl   $0x0,-0x3c(%rbp)
  jmp    L39
L230:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0xb000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x3c(%rbp)
L39:
  movzbl -0x15(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x3c(%rbp)
  jb     L230
  movl   $0x0,-0x38(%rbp)
  jmp    L18
L247:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0xc000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x38(%rbp)
L18:
  movzbl -0x14(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x38(%rbp)
  jb     L247
  movl   $0x0,-0x34(%rbp)
  jmp    L215
L59:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0xd000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x34(%rbp)
L215:
  movzbl -0x13(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x34(%rbp)
  jb     L59
  movl   $0x0,-0x30(%rbp)
  jmp    L214
L219:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0xe000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x30(%rbp)
L214:
  movzbl -0x12(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x30(%rbp)
  jb     L219
  movl   $0x0,-0x2c(%rbp)
  jmp    L208
L248:
  mov    -0x28(%rbp),%rax
  shr    $0x4,%rax
  mov    %rax,%rdx
  movabs $0xf000000000000000,%rax
  or     %rdx,%rax
  mov    %rax,-0x28(%rbp)
  addl   $0x1,-0x2c(%rbp)
L208:
  movzbl -0x11(%rbp),%eax
  movzbl %al,%eax
  cmp    %eax,-0x2c(%rbp)
  jb     L248
  mov    -0x28(%rbp),%rax
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L166
  call   <__stack_chk_fail@plt>
L166:
  leave
  ret
```

assistant: ```c
unsigned long davidegrayson_nibble_sort_counter_word(unsigned long w) {
  unsigned char frequency_map[0x10] = {0};
  frequency_map[w >> 0x00 & 0xf]++;
  frequency_map[w >> 0x04 & 0xf]++;
  frequency_map[w >> 0x08 & 0xf]++;
  frequency_map[w >> 0x0c & 0xf]++;
  frequency_map[w >> 0x10 & 0xf]++;
  frequency_map[w >> 0x14 & 0xf]++;
  frequency_map[w >> 0x18 & 0xf]++;
  frequency_map[w >> 0x1c & 0xf]++;
  frequency_map[w >> 0x20 & 0xf]++;
  frequency_map[w >> 0x24 & 0xf]++;
  frequency_map[w >> 0x28 & 0xf]++;
  frequency_map[w >> 0x2c & 0xf]++;
  frequency_map[w >> 0x30 & 0xf]++;
  frequency_map[w >> 0x34 & 0xf]++;
  frequency_map[w >> 0x38 & 0xf]++;
  frequency_map[w >> 0x3c & 0xf]++;
  unsigned long r = 0;
  for (unsigned int j = 0; j < frequency_map[0x1]; j++)
    r = ((unsigned long)0x1 << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0x2]; j++)
    r = ((unsigned long)0x2 << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0x3]; j++)
    r = ((unsigned long)0x3 << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0x4]; j++)
    r = ((unsigned long)0x4 << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0x5]; j++)
    r = ((unsigned long)0x5 << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0x6]; j++)
    r = ((unsigned long)0x6 << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0x7]; j++)
    r = ((unsigned long)0x7 << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0x8]; j++)
    r = ((unsigned long)0x8 << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0x9]; j++)
    r = ((unsigned long)0x9 << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0xa]; j++)
    r = ((unsigned long)0xa << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0xb]; j++)
    r = ((unsigned long)0xb << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0xc]; j++)
    r = ((unsigned long)0xc << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0xd]; j++)
    r = ((unsigned long)0xd << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0xe]; j++)
    r = ((unsigned long)0xe << 60) | (r >> 4);
  for (unsigned int j = 0; j < frequency_map[0xf]; j++)
    r = ((unsigned long)0xf << 60) | (r >> 4);
  return r;
}
```