user: 下面的汇编指令对应的C源代码是什么：

```asm
<virtio_load_direct>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    %rcx,-0x40(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %eax,-0x14(%rbp)
  mov    -0x30(%rbp),%rax
  shr    $0x20,%rax
  add    $0x1,%eax
  and    $0xffff,%eax
  mov    %eax,-0x10(%rbp)
  mov    -0x30(%rbp),%rax
  shr    $0x30,%rax
  mov    %eax,-0xc(%rbp)
  mov    -0x40(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  lea    D79(%rip),%rax
  mov    %rax,%rdi
  call   <early_puts@plt>
  mov    -0x28(%rbp),%rax
  movzbl %al,%eax
  mov    %eax,%esi
  lea    D19(%rip),%rax
  mov    %rax,%rdi
  call   <debug_print_int@plt>
  mov    -0x30(%rbp),%rax
  movzbl %al,%eax
  mov    %eax,%esi
  lea    D77(%rip),%rax
  mov    %rax,%rdi
  call   <debug_print_int@plt>
  mov    -0x38(%rbp),%rax
  movzbl %al,%eax
  mov    %eax,%esi
  lea    D6(%rip),%rax
  mov    %rax,%rdi
  call   <debug_print_int@plt>
  mov    -0x40(%rbp),%rax
  mov    %rax,%rsi
  lea    D31(%rip),%rax
  mov    %rax,%rdi
  call   <debug_print_addr@plt>
  cmpl   $0x200,-0xc(%rbp)
  je     L7
  mov    -0xc(%rbp),%eax
  movzbl %al,%eax
  mov    %eax,%esi
  lea    D82(%rip),%rax
  mov    %rax,%rdi
  call   <debug_print_int@plt>
  mov    $0xffffffffffffffff,%rax
  jmp    L18
L7:
  lea    D29(%rip),%rax
  mov    %rax,%rdi
  call   <virtio_puts@plt>
  mov    -0x8(%rbp),%rcx
  mov    -0x10(%rbp),%edx
  mov    -0x14(%rbp),%eax
  mov    %rcx,%rsi
  mov    %eax,%edi
  call   <virtio_read_many@plt>
  mov    %al,-0x15(%rbp)
  cmpb   $0x0,-0x15(%rbp)
  je     L26
  movzbl -0x15(%rbp),%eax
  mov    %eax,%esi
  lea    D87(%rip),%rax
  mov    %rax,%rdi
  call   <debug_print_int@plt>
  lea    D35(%rip),%rax
  mov    %rax,%rdi
  call   <virtio_panic@plt>
L26:
  mov    -0x10(%rbp),%eax
  shl    $0x9,%eax
  cltq
  add    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
L18:
  leave
  ret
```

tool_calls: name: retrieve_data
arguments: data_label: D79
data_type: string
name: retrieve_data
arguments: data_label: D19
data_type: string
name: retrieve_data
arguments: data_label: D77
data_type: string
name: retrieve_data
arguments: data_label: D6
data_type: string
name: retrieve_data
arguments: data_label: D31
data_type: string
name: retrieve_data
arguments: data_label: D82
data_type: string
name: retrieve_data
arguments: data_label: D29
data_type: string
name: retrieve_data
arguments: data_label: D87
data_type: string
name: retrieve_data
arguments: data_label: D35
data_type: string

tool: D79: _load_direct


tool: D19: rec_list1

tool: D77: rec_list2

tool: D6: subchan_id

tool: D31: load_addr

tool: D82: sector size invalid

tool: D29: .

tool: D87: load_direct status

tool: D35: I/O Error

assistant: ```c
unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2, unsigned long subchan_id, void *load_addr) {
  unsigned char status;
  int sec = rec_list1;
  int sec_num = (((rec_list2 >> 32) + 1) & 0xffff);
  int sec_len = rec_list2 >> 48;
  unsigned long addr = (unsigned long)load_addr;
  int i;
  early_puts("_load_direct\n");
  debug_print_int("rec_list1", rec_list1);
  debug_print_int("rec_list2", rec_list2);
  debug_print_int("subchan_id", subchan_id);
  debug_print_addr("load_addr", load_addr);
  if (sec_len != 512) {
    debug_print_int("sector size invalid", sec_len);
    return -1;
  }
  virtio_puts(".");
  status = virtio_read_many(sec, (void *)addr, sec_num);
  if (status) {
    debug_print_int("load_direct status", status);
    virtio_panic("I/O Error");
  }
  addr += sec_num * 512;
  return addr;
}
```