user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<main>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  mov    %rsi,%rbp
  push   %rbx
  mov    %edi,%ebx
  lea    D121(%rip),%rdi
  sub    $0x48,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x38(%rsp)
  xor    %eax,%eax
  movq   $0x0,(%rsp)
  movq   $0x0,0x8(%rsp)
  movq   $0x0,0x10(%rsp)
  movq   $0x0,0x18(%rsp)
  movq   $0x0,0x20(%rsp)
  movq   $0x0,0x28(%rsp)
  movq   $0x0,0x30(%rsp)
  call   <puts@plt>
  cmp    $0x1,%ebx
  jle    L56
  mov    0x8(%rbp),%r12
  cmpb   $0x2d,(%r12)
  jne    L80
  cmpb   $0x68,0x1(%r12)
  jne    L80
  cmpb   $0x0,0x2(%r12)
  jne    L80
L212:
  lea    D35(%rip),%rdi
  xor    %r13d,%r13d
  call   <puts@plt>
  lea    D32(%rip),%rdi
  call   <puts@plt>
  lea    D86(%rip),%rdi
  call   <puts@plt>
  lea    D46(%rip),%rdi
  call   <puts@plt>
  lea    D88(%rip),%rdi
  call   <puts@plt>
L271:
  mov    0x38(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L126
  add    $0x48,%rsp
  mov    %r13d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopw   0x0(%rax,%rax,1)
L80:
  lea    D119(%rip),%rsi
  mov    %r12,%rdi
  call   <strcmp@plt>
  test   %eax,%eax
  je     L212
  lea    D55(%rip),%rsi
  mov    %r12,%rdi
  call   <strcmp@plt>
  test   %eax,%eax
  je     L212
  mov    $0x1,%r13d
  cmp    $0x5,%ebx
  jne    L271
  lea    0x18(%rsp),%rdx
  mov    %rsp,%rsi
  mov    %r12,%rdi
  mov    0x10(%rbp),%r15
  mov    0x18(%rbp),%r14
  mov    0x20(%rbp),%rbp
  call   <loader_read@plt>
  cmpq   $0x0,(%rsp)
  je     L177
  cmpq   $0x0,0x18(%rsp)
  jne    L183
L177:
  mov    0x10(%rsp),%rdi
  test   %rdi,%rdi
  jne    L121
L20:
  mov    0x8(%rsp),%r8
  test   %r8,%r8
  je     L35
L117:
  mov    %r8,%rdi
  call   <free@plt>
  movq   $0x0,0x8(%rsp)
L35:
  mov    (%rsp),%rdi
  test   %rdi,%rdi
  je     L271
  call   <free@plt>
  jmp    L271
L47:
  mov    0x10(%rsp),%rdi
  mov    $0x1,%r13d
  test   %rdi,%rdi
  je     L117
L121:
  call   <free@plt>
  movq   $0x0,0x10(%rsp)
  jmp    L20
L56:
  mov    0x0(%rbp),%rsi
  lea    D27(%rip),%rdi
  xor    %eax,%eax
  xor    %r13d,%r13d
  call   <printf@plt>
  jmp    L271
L183:
  mov    %r15,%rdi
  lea    0x28(%rsp),%rdx
  lea    0x10(%rsp),%rsi
  call   <splash_read@plt>
  mov    0x10(%rsp),%rdi
  test   %rdi,%rdi
  je     L20
  cmpq   $0x0,0x28(%rsp)
  je     L121
  lea    0x20(%rsp),%rdx
  lea    0x8(%rsp),%rsi
  mov    %r14,%rdi
  call   <zero_bin_read@plt>
  mov    0x8(%rsp),%r8
  test   %r8,%r8
  je     L165
  mov    0x20(%rsp),%r12
  test   %r12,%r12
  je     L47
  mov    0x28(%rsp),%rsi
  add    %r12,%rsi
  add    $0x2010,%rsi
  mov    %rsi,0x18(%rsp)
  cmp    $0xfc000,%rsi
  ja     L129
  mov    (%rsp),%rbx
  mov    $0x6006010,%edi
  call   <bswap_ul@plt>
  mov    %r12,%rdi
  mov    %rax,0x2000(%rbx)
  mov    (%rsp),%rbx
  call   <bswap_ul@plt>
  mov    0x8(%rsp),%rsi
  mov    %r12,%rdx
  mov    %rax,0x2004(%rbx)
  mov    (%rsp),%rax
  lea    0x2010(%rax),%rdi
  call   <memcpy@plt>
  mov    0x20(%rsp),%rbx
  mov    (%rsp),%r13
  mov    0x28(%rsp),%r12
  lea    0x6006010(%rbx),%rdi
  call   <bswap_ul@plt>
  mov    %r12,%rdi
  mov    %rax,0x2008(%r13)
  mov    (%rsp),%r13
  call   <bswap_ul@plt>
  mov    0x10(%rsp),%rsi
  mov    %r12,%rdx
  mov    %rax,0x200c(%r13)
  mov    (%rsp),%rax
  lea    0x2010(%rax,%rbx,1),%rdi
  call   <memcpy@plt>
  lea    0x30(%rsp),%rdi
  lea    D39(%rip),%rdx
  mov    %rbp,%rsi
  call   <fopen_s@plt>
  mov    0x30(%rsp),%rcx
  test   %rcx,%rcx
  je     L73
  mov    0x18(%rsp),%rdx
  mov    (%rsp),%rdi
  mov    $0x1,%esi
  xor    %r13d,%r13d
  call   <fwrite@plt>
  mov    0x30(%rsp),%rdi
  call   <fclose@plt>
  mov    0x18(%rsp),%rsi
  lea    D114(%rip),%rdi
  xor    %eax,%eax
  movq   $0x0,0x30(%rsp)
  mov    %rsi,%rdx
  shr    $0xa,%rdx
  call   <printf@plt>
  jmp    L177
L129:
  mov    $0xfc000,%edx
  lea    D51(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  jmp    L177
L165:
  mov    0x10(%rsp),%rdi
  test   %rdi,%rdi
  je     L35
  jmp    L121
L73:
  mov    %rbp,%rsi
  lea    D56(%rip),%rdi
  xor    %eax,%eax
  mov    $0x1,%r13d
  call   <printf@plt>
  jmp    L177
L126:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: read_data
arguments: tag: D121
type_infered: string
name: read_data
arguments: tag: D35
type_infered: string
name: read_data
arguments: tag: D32
type_infered: string
name: read_data
arguments: tag: D86
type_infered: string
name: read_data
arguments: tag: D46
type_infered: string
name: read_data
arguments: tag: D88
type_infered: string
name: read_data
arguments: tag: D119
type_infered: string
name: read_data
arguments: tag: D55
type_infered: string
name: read_data
arguments: tag: D27
type_infered: string
name: read_data
arguments: tag: D39
type_infered: string
name: read_data
arguments: tag: D114
type_infered: string
name: read_data
arguments: tag: D51
type_infered: string
name: read_data
arguments: tag: D56
type_infered: string

tool: D121: --- mksplash v0.1 by cafe-alpha. ---

tool: D35:  Note: uses LibLZF: http://oldhome.schmorp.de/marc/liblzf.html

tool: D32:  Usage : <loader.bin> <splash.bmp> <0.bin> <out.bin>

tool: D86:          -> Pack loader.bin, splash.bmp, 0.bin in out.bin file.

tool: D46:             After startup, splash.bmp is displayed

tool: D88:             and 0.bin is loaded after a key is pressed.

tool: D119: -help

tool: D55: -?

tool: D27:  Type %s -h for help.


tool: D39: wb

tool: D114: Wrote %d bytes (%d KB) to disk.


tool: D51: Error : total size too big (required %d bytes, max %d bytes) !


tool: D56: Error : could not write to file (%s) !


assistant: ```c
int main(int argc, char *argv[]) {
  int ret = 1;
  char *file_loader;
  char *file_splash;
  char *file_zero;
  char *file_out;
  unsigned char *buff_out = NULL;
  unsigned char *buff_zero = NULL;
  unsigned char *buff_splash = NULL;
  unsigned long len_out = 0;
  unsigned long len_zero = 0;
  unsigned long len_splash = 0;
  unsigned long *ptr;
  unsigned long ofs, len;
  FILE *fp = NULL;
  printf("--- mksplash v0.1 by cafe-alpha. ---\n");
  if (argc <= 1) {
    printf(" Type %s -h for help.\n", argv[0]);
    return 0;
  }
  if (argc >= 2) {
    if ((!strcmp(argv[1], "-h")) || (!strcmp(argv[1], "-help")) || (!strcmp(argv[1], "-?"))) {
      printf(" Note: uses LibLZF: http://oldhome.schmorp.de/marc/liblzf.html\n");
      printf(" Usage : <loader.bin> <splash.bmp> <0.bin> <out.bin>\n");
      printf("         -> Pack loader.bin, splash.bmp, 0.bin in out.bin file.\n");
      printf("            After startup, splash.bmp is displayed\n");
      printf("            and 0.bin is loaded after a key is pressed.\n");
      return 0;
    }
  }
  if (argc != 5)
    return 1;
  file_loader = argv[1];
  file_splash = argv[2];
  file_zero = argv[3];
  file_out = argv[4];
  loader_read(file_loader, &buff_out, &len_out);
  if ((buff_out == NULL) || (len_out == 0))
    goto end;
  splash_read(file_splash, &buff_splash, &len_splash);
  if ((buff_splash == NULL) || (len_splash == 0))
    goto end;
  zero_bin_read(file_zero, &buff_zero, &len_zero);
  if ((buff_zero == NULL) || (len_zero == 0))
    goto end;
  len_out = (8 * 1024) + (16) + len_zero + len_splash;
  if (len_out > (1024 * 1024 - 0x4000)) {
    printf("Error : total size too big (required %d bytes, max %d bytes) !\n", len_out, (1024 * 1024 - 0x4000));
    goto end;
  }
  ofs = (8 * 1024) + (16);
  len = len_zero;
  ptr = (unsigned long *)(buff_out + ((8 * 1024) + 0));
  *ptr = bswap_ul(0x06004000 + ofs);
  ptr = (unsigned long *)(buff_out + ((8 * 1024) + 4));
  *ptr = bswap_ul(len);
  memcpy((void *)(buff_out + ofs), (void *)buff_zero, len);
  ofs = (8 * 1024) + (16) + len_zero;
  len = len_splash;
  ptr = (unsigned long *)(buff_out + ((8 * 1024) + 8));
  *ptr = bswap_ul(0x06004000 + ofs);
  ptr = (unsigned long *)(buff_out + ((8 * 1024) + 12));
  *ptr = bswap_ul(len);
  memcpy((void *)(buff_out + ofs), (void *)buff_splash, len);
  fopen_s(&fp, file_out, "wb");
  if (fp) {
    fwrite(buff_out, 1, len_out, fp);
    fclose(fp);
    fp = NULL;
    printf("Wrote %d bytes (%d KB) to disk.\n", len_out, len_out >> 10);
  } else {
    printf("Error : could not write to file (%s) !\n", file_out);
    goto end;
  }
  ret = 0;
end:
  if (buff_splash) {
    free(buff_splash);
    buff_splash = NULL;
  }
  if (buff_zero) {
    free(buff_zero);
    buff_zero = NULL;
  }
  if (buff_out) {
    free(buff_out);
    buff_out = NULL;
  }
  return ret;
}
```