user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<fd_timed_read_n>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rsi,0x8(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x28(%rsp)
  xor    %eax,%eax
  test   %edi,%edi
  js     L30
  mov    %edi,%r14d
  mov    %rdx,%r13
  mov    %rcx,%rbp
  test   %rsi,%rsi
  je     L30
  mov    %edi,0x1c(%rsp)
  mov    D14(%rip),%rax
  mov    (%rax),%eax
  mov    %eax,0x20(%rsp)
  test   %r8d,%r8d
  je     L16
  test   %rdx,%rdx
  je     L16
  mov    %rdx,%r15
  mov    $0xffffffff,%ebx
L135:
  mov    %r15,%rdx
  mov    0x8(%rsp),%rsi
  mov    %r14d,%edi
  call   <read@plt>
  test   %eax,%eax
  js     L233
  je     L44
  cltq
  sub    %rax,%r15
  test   %ebx,%ebx
  je     L44
  add    %rax,0x8(%rsp)
  jmp    L1
L30:
  mov    D72(%rip),%rax
  mov    (%rax),%rdx
  mov    D163(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffff,%eax
  jmp    L27
L16:
  mov    %r13,%r15
L1:
  lea    0x1c(%rsp),%r12
  test   %r15,%r15
  je     L44
L181:
  mov    %rbp,%rdi
  call   <_fd_get_poll_timeout@plt>
  mov    %eax,%ebx
  mov    %eax,%edx
  mov    $0x1,%esi
  mov    %r12,%rdi
  call   <poll@plt>
  test   %eax,%eax
  jns    L51
  mov    D163(%rip),%rax
  mov    (%rax),%rax
  mov    D104(%rip),%rdx
  cmp    (%rdx),%rax
  je     L181
  mov    D58(%rip),%rdx
  cmp    (%rdx),%rax
  je     L181
  mov    $0xffffffff,%eax
  jmp    L27
L51:
  jne    L84
  mov    D147(%rip),%rax
  mov    (%rax),%rdx
  mov    D163(%rip),%rax
  mov    %rdx,(%rax)
L44:
  mov    %r13d,%eax
  sub    %r15d,%eax
L27:
  mov    0x28(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L4
  add    $0x38,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L84:
  mov    0x24(%rsp),%edi
  mov    D170(%rip),%rax
  mov    %edi,%ecx
  and    (%rax),%ecx
  jne    L182
  mov    D69(%rip),%rax
  mov    %edi,%ecx
  and    (%rax),%ecx
  jne    L19
  mov    D14(%rip),%rax
  and    (%rax),%edi
  call   <assert@plt>
  jmp    L135
L182:
  mov    D149(%rip),%rax
  mov    (%rax),%rdx
  mov    D163(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffff,%eax
  jmp    L27
L19:
  mov    D105(%rip),%rax
  mov    (%rax),%rdx
  mov    D163(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffff,%eax
  jmp    L27
L233:
  mov    D163(%rip),%rax
  mov    (%rax),%rax
  mov    D104(%rip),%rdx
  cmp    (%rdx),%rax
  je     L1
  mov    D58(%rip),%rdx
  cmp    (%rdx),%rax
  je     L1
  mov    $0xffffffff,%eax
  jmp    L27
L4:
  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);
}
```