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

```asm
<fd_timed_read_n>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %edi,0x8(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x28(%rsp)
  xor    %eax,%eax
  test   %edi,%edi
  js     L72
  mov    %rsi,%r14
  test   %rsi,%rsi
  je     L72
  mov    D1(%rip),%rax
  mov    %rdx,%r12
  mov    %rcx,%rbx
  mov    %rdx,%r15
  movd   %edi,%xmm0
  mov    (%rax),%eax
  movd   %eax,%xmm1
  mov    %eax,0xc(%rsp)
  punpckldq %xmm1,%xmm0
  movq   %xmm0,0x18(%rsp)
  test   %r8d,%r8d
  je     L111
  mov    $0xffffffff,%r13d
  test   %rdx,%rdx
  je     L111
L78:
  mov    0x8(%rsp),%edi
  mov    %r15,%rdx
  mov    %r14,%rsi
  call   <read@plt>
  test   %eax,%eax
  js     L219
  je     L124
  cltq
  sub    %rax,%r15
  test   %r13d,%r13d
  jne    L104
  nopl   (%rax)
L124:
  mov    %r12d,%eax
  sub    %r15d,%eax
L94:
  mov    0x28(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L75
  add    $0x38,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L104:
  add    %rax,%r14
  nopl   0x0(%rax)
L111:
  test   %r15,%r15
  je     L124
L117:
  lea    0x18(%rsp),%rbp
  nopw   0x0(%rax,%rax,1)
L226:
  mov    %rbx,%rdi
  call   <_fd_get_poll_timeout@plt>
  mov    $0x1,%esi
  mov    %rbp,%rdi
  mov    %eax,%edx
  mov    %eax,%r13d
  call   <poll@plt>
  test   %eax,%eax
  jns    L147
  mov    D116(%rip),%rax
  mov    D84(%rip),%rdx
  mov    (%rax),%rax
  cmp    (%rdx),%rax
  je     L226
  mov    D131(%rip),%rdx
  cmp    (%rdx),%rax
  je     L226
L192:
  mov    $0xffffffff,%eax
  jmp    L94
  nopw   0x0(%rax,%rax,1)
L147:
  je     L41
  mov    0x20(%rsp),%edi
  mov    D159(%rip),%rax
  mov    %edi,%ecx
  and    (%rax),%ecx
  jne    L145
  mov    D88(%rip),%rax
  mov    %edi,%ecx
  and    (%rax),%ecx
  jne    L87
  mov    D1(%rip),%rax
  and    (%rax),%edi
  call   <assert@plt>
  jmp    L78
  nopl   0x0(%rax,%rax,1)
L41:
  mov    D80(%rip),%rax
  mov    (%rax),%rdx
  mov    D116(%rip),%rax
  mov    %rdx,(%rax)
  jmp    L124
  nopl   0x0(%rax)
L219:
  mov    D116(%rip),%rax
  mov    D84(%rip),%rdx
  mov    (%rax),%rax
  cmp    (%rdx),%rax
  je     L117
  mov    D131(%rip),%rdx
  cmp    (%rdx),%rax
  je     L117
  jmp    L192
L72:
  mov    D77(%rip),%rax
  mov    (%rax),%rdx
  mov    D116(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffff,%eax
  jmp    L94
L87:
  mov    D128(%rip),%rax
  mov    (%rax),%rdx
  mov    D116(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffff,%eax
  jmp    L94
L145:
  mov    D39(%rip),%rax
  mov    (%rax),%rdx
  mov    D116(%rip),%rax
  mov    %rdx,(%rax)
  jmp    L192
L75:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
ssize_t fd_timed_read_n(int fd, void *buf, size_t n, const struct timeval *when, int do_skip_first_poll) {
  unsigned char *p;
  int msecs;
  struct pollfd pfd;
  int nfd;
  size_t nleft;
  ssize_t nread;
  if ((fd < 0) || (buf == NULL)) {
    errno = EINVAL;
    return (-1);
  }
  p = buf;
  nleft = n;
  pfd.fd = fd;
  pfd.events = POLLIN;
  if (do_skip_first_poll && (nleft > 0)) {
    msecs = -1;
    goto read_me;
  }
  while (nleft > 0) {
    msecs = _fd_get_poll_timeout(when);
    nfd = poll(&pfd, 1, msecs);
    if (nfd < 0) {
      if ((errno == EINTR) || (errno == EAGAIN))
        continue;
      else
        return (-1);
    } else if (nfd == 0) {
      errno = ETIMEDOUT;
      break;
    } else if (pfd.revents & POLLNVAL) {
      errno = EBADF;
      return (-1);
    } else if (pfd.revents & POLLERR) {
      errno = EIO;
      return (-1);
    }
    assert(pfd.revents & POLLIN);
  read_me:
    nread = read(fd, p, nleft);
    if (nread < 0) {
      if ((errno == EINTR) || (errno == EAGAIN))
        continue;
      else
        return (-1);
    } else if (nread == 0) {
      break;
    }
    nleft -= nread;
    p += nread;
    if (msecs == 0) {
      break;
    }
  }
  return (n - nleft);
}
```