user: 请将以下的汇编代码转换成C语言代码：

```asm
<main_loop>:
  endbr64
  push   %r15
  lea    D24(%rip),%r15
  push   %r14
  push   %r13
  push   %r12
  mov    %esi,%r12d
  push   %rbp
  mov    %edx,%ebp
  push   %rbx
  sub    $0x478,%rsp
  mov    %edi,0x3c(%rsp)
  lea    0x48(%rsp),%rbx
  lea    0x60(%rsp),%r14
  mov    %fs:0x28,%rax
  mov    %rax,0x468(%rsp)
  xor    %eax,%eax
  lea    0x4c(%rsp),%rax
  movl   $0x0,0x4c(%rsp)
  mov    %rax,0x28(%rsp)
  lea    0x58(%rsp),%rax
  mov    %rax,0x10(%rsp)
  lea    0x50(%rsp),%rax
  mov    %rax,0x20(%rsp)
  lea    0x5c(%rsp),%rax
  mov    %rax,0x18(%rsp)
  lea    0x54(%rsp),%rax
  mov    %rax,(%rsp)
  lea    0x3c(%rsp),%rax
  movl   $0x0,0x50(%rsp)
  movl   $0x0,0x54(%rsp)
  movl   $0xffffffff,0x58(%rsp)
  movl   $0xffffffff,0x5c(%rsp)
  mov    %rax,0x8(%rsp)
  nopl   (%rax)
L131:
  mov    %rbx,%rdi
  call   <FD_ZERO@plt>
  mov    0x58(%rsp),%edi
  mov    %rbx,%rsi
  test   %edi,%edi
  cmovs  %r12d,%edi
  call   <FD_SET@plt>
  mov    0x5c(%rsp),%edi
  mov    %rbx,%rsi
  test   %edi,%edi
  cmovs  %ebp,%edi
  call   <FD_SET@plt>
  mov    0x3c(%rsp),%edi
  mov    %rbx,%rsi
  call   <FD_SET@plt>
  mov    0x5c(%rsp),%eax
  mov    0x58(%rsp),%edi
  mov    %rbx,%rsi
  cmp    %eax,%edi
  cmovl  %eax,%edi
  mov    0x3c(%rsp),%eax
  cmp    %eax,%edi
  cmovl  %eax,%edi
  cmp    %ebp,%edi
  cmovl  %ebp,%edi
  cmp    %r12d,%edi
  cmovl  %r12d,%edi
  xor    %r8d,%r8d
  xor    %ecx,%ecx
  xor    %edx,%edx
  add    $0x1,%edi
  call   <select@plt>
  test   %rax,%rax
  jns    L176
  mov    %r15,%rdi
  call   <perror@plt>
  jmp    L131
  nopw   0x0(%rax,%rax,1)
L176:
  mov    %rbx,%rsi
  mov    %r12d,%edi
  call   <FD_ISSET@plt>
  test   %rax,%rax
  jne    L47
L30:
  mov    %rbx,%rsi
  mov    %ebp,%edi
  call   <FD_ISSET@plt>
  test   %rax,%rax
  jne    L113
L32:
  mov    0x4c(%rsp),%ecx
  test   %ecx,%ecx
  jne    L255
  mov    0x58(%rsp),%edi
  test   %edi,%edi
  jns    L278
L143:
  mov    0x50(%rsp),%edx
  test   %edx,%edx
  jne    L315
L97:
  mov    0x5c(%rsp),%edi
  test   %edi,%edi
  jns    L294
L67:
  mov    0x54(%rsp),%eax
  test   %eax,%eax
  jne    L239
  mov    0x3c(%rsp),%edi
  mov    %rbx,%rsi
  call   <FD_ISSET@plt>
  test   %rax,%rax
  je     L131
L239:
  mov    (%rsp),%rcx
  mov    0x8(%rsp),%rdi
  mov    $0x400,%edx
  mov    %r14,%rsi
  call   <receive_data@plt>
  test   %rax,%rax
  je     L131
  add    %r14,%rax
  mov    %rbx,0x30(%rsp)
  mov    %r14,%rbx
  mov    %rax,%r13
  jmp    L53
  nopl   0x0(%rax,%rax,1)
L246:
  mov    0x58(%rsp),%edi
  test   %edi,%edi
  jns    L10
L86:
  add    $0x1,%rbx
  cmp    %r13,%rbx
  je     L220
L53:
  movzbl (%rbx),%eax
  test   %al,%al
  jns    L246
  mov    0x5c(%rsp),%edi
  test   %edi,%edi
  js     L86
  and    $0x7f,%eax
  mov    $0x1,%edx
  mov    %rbx,%rsi
  mov    %al,(%rbx)
  call   <write@plt>
  test   %rax,%rax
  jns    L86
  lea    D47(%rip),%rdi
  add    $0x1,%rbx
  call   <perror@plt>
  mov    0x18(%rsp),%rdi
  call   <close_conn@plt>
  movl   $0x0,0x50(%rsp)
  cmp    %r13,%rbx
  jne    L53
  nopw   0x0(%rax,%rax,1)
L220:
  mov    0x30(%rsp),%rbx
  jmp    L131
  nopw   0x0(%rax,%rax,1)
L278:
  mov    %rbx,%rsi
  call   <FD_ISSET@plt>
  test   %rax,%rax
  je     L143
L255:
  mov    0x28(%rsp),%rcx
  mov    0x10(%rsp),%rdi
  mov    $0x400,%edx
  mov    %r14,%rsi
  call   <receive_data@plt>
  mov    %rax,%r13
  test   %rax,%rax
  je     L143
  mov    %rax,%rsi
  mov    %r14,%rdi
  call   <clear_high_bit@plt>
  mov    0x3c(%rsp),%edi
  mov    %r13d,%edx
  mov    %r14,%rsi
  call   <write@plt>
  test   %rax,%rax
  jns    L143
  lea    D47(%rip),%rdi
  call   <perror@plt>
  mov    0x50(%rsp),%edx
  test   %edx,%edx
  je     L97
  nopw   0x0(%rax,%rax,1)
L315:
  mov    0x20(%rsp),%rcx
  mov    0x18(%rsp),%rdi
  mov    $0x400,%edx
  mov    %r14,%rsi
  call   <receive_data@plt>
  mov    %rax,%r13
  test   %rax,%rax
  je     L67
  mov    %rax,%rsi
  mov    %r14,%rdi
  call   <set_high_bit@plt>
  mov    0x3c(%rsp),%edi
  mov    %r13d,%edx
  mov    %r14,%rsi
  call   <write@plt>
  test   %rax,%rax
  jns    L67
  lea    D47(%rip),%rdi
  call   <perror@plt>
  jmp    L67
  nopw   0x0(%rax,%rax,1)
L10:
  mov    $0x1,%edx
  mov    %rbx,%rsi
  call   <write@plt>
  test   %rax,%rax
  jns    L86
  lea    D47(%rip),%rdi
  call   <perror@plt>
  mov    0x10(%rsp),%rdi
  call   <close_conn@plt>
  movl   $0x0,0x4c(%rsp)
  jmp    L86
  nopl   0x0(%rax)
L113:
  mov    0x5c(%rsp),%edi
  shr    $0x1f,%edi
  call   <assert@plt>
  mov    %ebp,%edi
  call   <accept_conn@plt>
  mov    %eax,0x5c(%rsp)
  jmp    L32
  nopl   0x0(%rax)
L47:
  mov    0x58(%rsp),%edi
  shr    $0x1f,%edi
  call   <assert@plt>
  mov    %r12d,%edi
  call   <accept_conn@plt>
  mov    %eax,0x58(%rsp)
  jmp    L30
  nopl   (%rax)
L294:
  mov    %rbx,%rsi
  call   <FD_ISSET@plt>
  test   %rax,%rax
  jne    L315
  jmp    L67
```

tool_calls: name: unpack_data
arguments: label: D24
type: string
name: unpack_data
arguments: label: D47
type: string

tool: D24: select

tool: D47: write

assistant: ```c
void main_loop(int serial_fd, int low_listener, int high_listener) {
  fd_set rdfds;
  int low_poll = 0, high_poll = 0, serial_poll = 0;
  int low_fd = -1, high_fd = -1;
  while (1) {
    char buf[1024];
    ssize_t bytes;
    int max;
    FD_ZERO(&rdfds);
    FD_SET(low_fd < 0 ? low_listener : low_fd, &rdfds);
    FD_SET(high_fd < 0 ? high_listener : high_fd, &rdfds);
    FD_SET(serial_fd, &rdfds);
    max = ((low_fd) < (low_listener) ? (low_listener) : (low_fd));
    max = ((max) < (high_fd) ? (high_fd) : (max));
    max = ((max) < (high_listener) ? (high_listener) : (max));
    max = ((max) < (serial_fd) ? (serial_fd) : (max));
    if (select(max + 1, &rdfds, NULL, NULL, NULL) < 0) {
      perror("select");
      continue;
    }
    if (FD_ISSET(low_listener, &rdfds)) {
      assert(low_fd < 0);
      low_fd = accept_conn(low_listener);
    }
    if (FD_ISSET(high_listener, &rdfds)) {
      assert(high_fd < 0);
      high_fd = accept_conn(high_listener);
    }
    if (low_poll || (low_fd >= 0 && FD_ISSET(low_fd, &rdfds))) {
      if ((bytes = receive_data(&low_fd, &buf[0], sizeof(buf), &low_poll)) > 0) {
        clear_high_bit(&buf[0], bytes);
        if (write(serial_fd, &buf[0], bytes) < 0)
          perror("write");
      }
    }
    if (high_poll || (high_fd >= 0 && FD_ISSET(high_fd, &rdfds))) {
      if ((bytes = receive_data(&high_fd, &buf[0], sizeof(buf), &high_poll)) > 0) {
        set_high_bit(&buf[0], bytes);
        if (write(serial_fd, &buf[0], bytes) < 0)
          perror("write");
      }
    }
    if (serial_poll || FD_ISSET(serial_fd, &rdfds)) {
      if ((bytes = receive_data(&serial_fd, &buf[0], sizeof(buf), &serial_poll)) > 0) {
        ssize_t i;
        for (i = 0; i < bytes; ++i) {
          if (buf[i] & 0x80) {
            if (high_fd >= 0) {
              buf[i] &= 0x7f;
              if ((write(high_fd, &buf[i], 1)) < 0) {
                perror("write");
                close_conn(&high_fd);
                high_poll = 0;
              }
            }
          } else {
            if (low_fd >= 0) {
              if ((write(low_fd, &buf[i], 1)) < 0) {
                perror("write");
                close_conn(&low_fd);
                low_poll = 0;
              }
            }
          }
        }
      }
    }
  }
}
```