user: 请从给定的汇编指令推导出C源代码：

```asm
<read_IntelHEX>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x448,%rsp
  mov    %rdi,0x10(%rsp)
  mov    %rsi,%rdi
  mov    %fs:0x28,%rax
  mov    %rax,0x438(%rsp)
  xor    %eax,%eax
  lea    D4(%rip),%rsi
  call   <fopen@plt>
  mov    %rax,%rdi
  mov    %rax,0x18(%rsp)
  mov    $0x0,%eax
  test   %rdi,%rdi
  je     L284
  lea    0x2c(%rsp),%rsi
  call   <fstat@plt>
  mov    0x2c(%rsp),%eax
  mov    %eax,0xc(%rsp)
  test   %eax,%eax
  je     L284
  mov    $0x0,%ebp
  lea    D8(%rip),%r12
  jmp    L184
L228:
  mov    $0x400,%eax
  mov    0xc(%rsp),%esi
  sub    %esi,%eax
  cltq
  lea    0x30(%rsp,%rax,1),%rax
  mov    %rax,%rbx
  mov    0x18(%rsp),%rcx
  mov    $0x1,%edx
  mov    %rax,%rdi
  call   <fread@plt>
  mov    0x18(%rsp),%rdi
  call   <fclose@plt>
  mov    %rbx,%rsi
  lea    0x1(%rbx),%rbx
  lea    0x430(%rsp),%rax
  cmp    %rax,%rsi
  jae    L284
  movl   $0x0,0xc(%rsp)
  jmp    L188
L216:
  movsbl %dil,%edi
  call   <Char2Int@plt>
  cmp    $0xff,%eax
  je     L49
  cmp    $0x9,%ebp
  jg     L16
  test   %ebp,%ebp
  js     L49
  cmp    $0x9,%ebp
  ja     L49
  mov    %ebp,%edx
  movslq (%r12,%rdx,4),%rdx
  add    %r12,%rdx
  notrack jmp *%rdx
L16:
  cmp    $0xfd,%ebp
  je     L179
  cmp    $0xfe,%ebp
  jne    L49
  shl    $0x4,%eax
  cmp    $0xf0,%eax
  sete   %al
  movzbl %al,%eax
  and    %r15d,%eax
  je     L284
  test   %r13,%r13
  jne    L8
  test   %r14d,%r14d
  je     L284
L8:
  mov    $0xff,%ebp
  jmp    L49
  shl    $0x4,%eax
  mov    %eax,0x8(%rsp)
  mov    $0x1,%ebp
  jmp    L49
  or     %eax,0x8(%rsp)
  mov    0x8(%rsp),%esi
  mov    %esi,%r15d
  mov    $0x2,%ebp
  jmp    L49
  mov    $0x0,%r14d
  add    $0x1,%ebp
  mov    $0x6,%ecx
  sub    %ebp,%ecx
  shl    $0x2,%ecx
  shl    %cl,%eax
  or     %eax,%r14d
  mov    %r14d,%eax
  sar    $0x8,%eax
  add    %r14d,%eax
  sub    %eax,%r15d
  movslq %r14d,%r13
  add    0x10(%rsp),%r13
L49:
  add    $0x1,%rbx
  lea    -0x1(%rbx),%rax
  lea    0x430(%rsp),%rdx
  cmp    %rax,%rdx
  jbe    L62
L188:
  movzbl (%rbx),%edi
  cmp    $0x3a,%dil
  jne    L216
  mov    $0x0,%ebp
  jmp    L49
  cmp    $0x1,%eax
  mov    $0x0,%edx
  cmove  %rdx,%r13
  cmove  %edx,%r14d
  mov    $0x8,%ebp
  mov    $0xfd,%eax
  cmove  %eax,%ebp
  jmp    L49
  shl    $0x4,%eax
  mov    %al,0x0(%r13)
  mov    $0x9,%ebp
  jmp    L49
  or     0x0(%r13),%al
  mov    %al,0x0(%r13)
  add    $0x1,%r13
  movsbl %al,%eax
  sub    %eax,%r15d
  subl   $0x1,0x8(%rsp)
  mov    0x8(%rsp),%eax
  test   %eax,%eax
  mov    $0x7,%ebp
  mov    $0xfd,%eax
  cmovle %eax,%ebp
  jmp    L49
L179:
  cmp    $0xf,%eax
  sete   %al
  movzbl %al,%eax
  and    %r15d,%eax
  je     L284
  mov    $0xfe,%ebp
  jmp    L49
L62:
  cmpl   $0x0,0xc(%rsp)
  je     L284
L184:
  mov    0xc(%rsp),%ebx
  cmp    $0x3ff,%ebx
  jle    L228
  lea    0x30(%rsp),%rdi
  mov    0x18(%rsp),%rcx
  mov    $0x1,%edx
  mov    $0x400,%esi
  call   <fread@plt>
  sub    $0x400,%ebx
  mov    %ebx,0xc(%rsp)
  lea    0x31(%rsp),%rbx
  jmp    L188
L284:
  mov    0x438(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L219
  add    $0x448,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L219:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: unpack_data
arguments: data_label: D4
data_type: string

tool: D4: rb

assistant: ```c
__attribute__((visibility("default"))) bool read_IntelHEX(void *ROM, char *file) {
  FILE *in_file;
  uint8_t parsed, lenght, checksum, mode = 0;
  uint16_t address;
  char buffer[1024];
  char *buffer_ptr;
  char *target_ptr;
  struct stat file_disc;
  if (!(in_file = fopen(file, "rb")))
    return false;
  fstat(in_file, &file_disc);
  for (int size = file_disc.st_size; size;) {
    if (size >= 1024) {
      fread(buffer_ptr = buffer, 1024, 1, in_file);
      size -= 1024;
    } else {
      fread(buffer_ptr = &buffer[1024 - size], size, 1, in_file);
      size = 0;
      fclose(in_file);
    }
    while (buffer_ptr++ < &buffer[1024]) {
      if (*buffer_ptr == ':')
        mode = 0;
      else if ((parsed = Char2Int(*buffer_ptr)) != 255) {
        switch (mode++) {
        case 0:
          lenght = parsed << 4;
          break;
        case 1:
          lenght |= parsed;
          checksum = lenght;
          break;
        case 2:
          address = 0;
        case 3:
        case 4:
        case 5:
          address |= parsed << (4 * (6 - mode));
          checksum -= address + (address >> 8);
          target_ptr = &ROM[address];
          break;
        case 7:
          if (parsed == 1) {
            mode += (253 - 8);
            target_ptr = NULL;
            address = 0;
          }
          break;
        case 8:
          *target_ptr = parsed << 4;
          break;
        case 9:
          *target_ptr |= parsed;
          checksum -= *(target_ptr++);
          if (--lenght > 0)
            mode = 7;
          else
            mode += (253 - 10);
          break;
        case 253:
          if (!(checksum & 0x0F == parsed))
            return false;
          break;
        case 254:
          if (!(checksum & 0xF0 == parsed << 4))
            return false;
          else if ((target_ptr == NULL) && (address == 0))
            return true;
          break;
        case 6:
        case 255:
        default:
          mode--;
          break;
        }
      }
    }
  }
}
```