user: Please show me the C implementation that matches the assembly code listed below:

```asm
<update_program>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x20,%rsp
  movl   $0x5fc00000,-0x10(%rbp)
  mov    -0x10(%rbp),%eax
  mov    %rax,-0x8(%rbp)
  movl   $0x0,-0x1c(%rbp)
  movl   $0x0,-0x18(%rbp)
  movl   $0x0,-0x14(%rbp)
  movl   $0x0,-0xc(%rbp)
  lea    D128(%rip),%rax
  mov    %rax,%rdi
  call   <uart_puts@plt>
  mov    $0x0,%eax
  call   <uart_get_file_size@plt>
  mov    %eax,-0xc(%rbp)
  lea    D58(%rip),%rax
  mov    %rax,%rdi
  call   <uart_printf@plt>
  mov    -0xc(%rbp),%eax
  mov    %eax,%edi
  call   <uart_print_int@plt>
  lea    D104(%rip),%rax
  mov    %rax,%rdi
  call   <uart_puts@plt>
L98:
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,%rdi
  call   <uart_get_file@plt>
  test   %rax,%rax
  je     L72
  movl   $0x1,-0x18(%rbp)
  movl   $0x0,-0x1c(%rbp)
  addl   $0x1,-0x14(%rbp)
  jmp    L116
L72:
  cmpl   $0x0,-0x18(%rbp)
  je     L116
  addl   $0x1,-0x1c(%rbp)
L116:
  mov    -0x14(%rbp),%eax
  cmp    -0xc(%rbp),%eax
  je     L17
  cmpl   $0xffffff,-0x1c(%rbp)
  je     L114
  jmp    L98
L17:
  nop
  jmp    L19
L114:
  nop
L19:
  cmpl   $0x0,-0x14(%rbp)
  jne    L104
  lea    D38(%rip),%rax
  mov    %rax,%rdi
  call   <uart_puts@plt>
  mov    $0xffffffff,%eax
  jmp    L23
L104:
  lea    D39(%rip),%rax
  mov    %rax,%rdi
  call   <uart_printf@plt>
  mov    -0x14(%rbp),%eax
  mov    %eax,%edi
  call   <uart_print_int@plt>
  lea    D8(%rip),%rax
  mov    %rax,%rdi
  call   <uart_printf@plt>
  lea    D57(%rip),%rax
  mov    %rax,%rdi
  call   <uart_printf@plt>
  mov    -0x10(%rbp),%eax
  lea    0xf(%rax),%edx
  mov    -0x10(%rbp),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <sdram_read@plt>
  lea    D117(%rip),%rax
  mov    %rax,%rdi
  call   <uart_printf@plt>
  mov    -0x14(%rbp),%edx
  mov    -0x10(%rbp),%eax
  add    %edx,%eax
  lea    -0x1(%rax),%edx
  mov    -0x14(%rbp),%ecx
  mov    -0x10(%rbp),%eax
  add    %ecx,%eax
  sub    $0x10,%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <sdram_read@plt>
  lea    D78(%rip),%rax
  mov    %rax,%rdi
  call   <uart_puts@plt>
  lea    D80(%rip),%rax
  mov    %rax,%rdi
  call   <uart_printf@plt>
  mov    $0x0,%eax
  call   <uart_getc@plt>
  mov    %al,-0x1d(%rbp)
  lea    D88(%rip),%rax
  mov    %rax,%rdi
  call   <uart_puts@plt>
  cmpb   $0x59,-0x1d(%rbp)
  je     L32
  cmpb   $0x79,-0x1d(%rbp)
  je     L32
  lea    D73(%rip),%rax
  mov    %rax,%rdi
  call   <uart_puts@plt>
  mov    $0xffffffff,%eax
  jmp    L23
L32:
  lea    D123(%rip),%rax
  mov    %rax,%rdi
  call   <uart_puts@plt>
  mov    $0x0,%edi
  call   <nand_erase_block@plt>
  mov    -0x14(%rbp),%edx
  mov    -0x10(%rbp),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <write_to_boot@plt>
  lea    D66(%rip),%rax
  mov    %rax,%rdi
  call   <uart_puts@plt>
  mov    $0x0,%eax
L23:
  leave
  ret
```

tool_calls: name: unpack_data
arguments: data_tag: D128
type_guessed: string
name: unpack_data
arguments: data_tag: D58
type_guessed: string
name: unpack_data
arguments: data_tag: D104
type_guessed: string
name: unpack_data
arguments: data_tag: D38
type_guessed: string
name: unpack_data
arguments: data_tag: D39
type_guessed: string
name: unpack_data
arguments: data_tag: D8
type_guessed: string
name: unpack_data
arguments: data_tag: D57
type_guessed: string
name: unpack_data
arguments: data_tag: D117
type_guessed: string
name: unpack_data
arguments: data_tag: D78
type_guessed: string
name: unpack_data
arguments: data_tag: D80
type_guessed: string
name: unpack_data
arguments: data_tag: D88
type_guessed: string
name: unpack_data
arguments: data_tag: D73
type_guessed: string
name: unpack_data
arguments: data_tag: D123
type_guessed: string
name: unpack_data
arguments: data_tag: D66
type_guessed: string

tool: D128: Please send binary file!

tool: D58: file size = 

tool: D104: 
Receiving binary file ...

tool: D38: No file receive.

tool: D39: 
Received 

tool: D8:  bytes data.


tool: D57: 
The first 16 byte are:

tool: D117: 
The last 16 bytes are:

tool: D78: 
Do you sure update this program? (Y/n)

tool: D80:  >> 

tool: 

tool: D73: You have cancel update.

tool: D123: Updating ...

tool: D66: Update done!

assistant: ```c
int update_program(void) {
  unsigned int addr = 0x5FC00000;
  unsigned char *buffer = (unsigned char *)addr;
  unsigned int wait_time = 0;
  int start = 0;
  int length = 0;
  int size = 0;
  uart_puts("Please send binary file!");
  size = uart_get_file_size();
  uart_printf("file size = ");
  uart_print_int(size);
  uart_puts("\nReceiving binary file ...");
  while (1) {
    if (uart_get_file(&buffer[length])) {
      start = 1;
      wait_time = 0;
      ++length;
    } else {
      if (start)
        ++wait_time;
    }
    if (length == size)
      break;
    if (wait_time == 0x00FFFFFF)
      break;
  }
  if (length == 0) {
    uart_puts("No file receive.");
    return -1;
  }
  uart_printf("\nReceived ");
  uart_print_int(length);
  uart_printf(" bytes data.\n");
  uart_printf("\nThe first 16 byte are:");
  sdram_read(addr, addr + 0xF);
  uart_printf("\nThe last 16 bytes are:");
  sdram_read(addr + length - 1 - 0xF, addr + length - 1);
  uart_puts("\nDo you sure update this program? (Y/n)");
  uart_printf(" >> ");
  char ch = uart_getc();
  uart_puts("");
  if (ch != 'Y' && ch != 'y') {
    uart_puts("You have cancel update.");
    return -1;
  }
  uart_puts("Updating ...");
  nand_erase_block(0);
  write_to_boot(addr, length);
  uart_puts("Update done!");
  return 0;
}
```