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

```asm
<fp_addexp>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x18(%rbp)
  mov    %esi,-0x1c(%rbp)
  mov    %edx,-0x20(%rbp)
  mov    %ecx,-0x24(%rbp)
  mov    -0x1c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x1c(%rbp)
  movslq %eax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  mov    -0x24(%rbp),%edx
  mov    %dl,(%rax)
  cmpl   $0x0,-0x20(%rbp)
  jns    L31
  negl   -0x20(%rbp)
  mov    -0x1c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x1c(%rbp)
  movslq %eax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movb   $0x2d,(%rax)
  jmp    L20
L31:
  mov    -0x1c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x1c(%rbp)
  movslq %eax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movb   $0x2b,(%rax)
L20:
  cmpl   $0x3e7,-0x20(%rbp)
  jle    L7
  mov    -0x20(%rbp),%eax
  movslq %eax,%rdx
  imul   $0x10624dd3,%rdx,%rdx
  shr    $0x20,%rdx
  sar    $0x6,%edx
  sar    $0x1f,%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  lea    0x30(%rax),%ecx
  mov    -0x1c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x1c(%rbp)
  movslq %eax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  mov    -0xc(%rbp),%eax
  imul   $0xfffffc18,%eax,%eax
  add    %eax,-0x20(%rbp)
L7:
  cmpl   $0x63,-0x20(%rbp)
  jle    L39
  mov    -0x20(%rbp),%eax
  movslq %eax,%rdx
  imul   $0x51eb851f,%rdx,%rdx
  shr    $0x20,%rdx
  sar    $0x5,%edx
  sar    $0x1f,%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x8(%rbp),%eax
  lea    0x30(%rax),%ecx
  mov    -0x1c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x1c(%rbp)
  movslq %eax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  mov    -0x8(%rbp),%eax
  imul   $0xffffff9c,%eax,%eax
  add    %eax,-0x20(%rbp)
L39:
  mov    -0x20(%rbp),%eax
  movslq %eax,%rdx
  imul   $0x66666667,%rdx,%rdx
  shr    $0x20,%rdx
  sar    $0x2,%edx
  sar    $0x1f,%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x4(%rbp),%eax
  lea    0x30(%rax),%ecx
  mov    -0x1c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x1c(%rbp)
  movslq %eax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  mov    -0x20(%rbp),%eax
  mov    %eax,%ecx
  mov    -0x4(%rbp),%eax
  mov    $0xfffffff6,%edx
  imul   %edx,%eax
  add    %ecx,%eax
  lea    0x30(%rax),%ecx
  mov    -0x1c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x1c(%rbp)
  movslq %eax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  mov    -0x1c(%rbp),%eax
  pop    %rbp
  ret
```

assistant: ```c
int fp_addexp(char *buff, int len, int dx, int ch) {
  int dxDiv10;
  buff[len++] = ch;
  if (dx < 0) {
    dx = -dx;
    buff[len++] = '-';
  } else
    buff[len++] = '+';
  if (dx >= 1000) {
    int dxDiv1000 = ((dx) / (1000));
    buff[len++] = '0' + dxDiv1000;
    dx = dx - dxDiv1000 * 1000;
  }
  if (dx >= 100) {
    int dxDiv100 = ((dx) / (100));
    buff[len++] = '0' + dxDiv100;
    dx = dx - dxDiv100 * 100;
  }
  dxDiv10 = ((dx) / 10);
  buff[len++] = '0' + dxDiv10;
  buff[len++] = '0' + dx - dxDiv10 * 10;
  return len;
}
```