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

```asm
<testSparse>:
  endbr64
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  mov    $0x0,%eax
  call   <cleanup@plt>
  mov    $0x500000,%esi
  lea    D86(%rip),%r12
  mov    %r12,%rdi
  call   <createZeroFile@plt>
  mov    %r12,%rdi
  call   <blocksCount@plt>
  mov    %rax,%rbp
  mov    $0x0,%r8d
  mov    $0x1,%ecx
  lea    D56(%rip),%rbx
  mov    %rbx,%rdx
  mov    %r12,%rsi
  lea    D143(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  mov    $0x500000,%edx
  mov    %rbx,%rsi
  lea    D115(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbx,%rdi
  call   <blocksCount@plt>
  cmp    %rax,%rbp
  setle  %r13b
  movzbl %r13b,%r13d
  mov    $0x63,%edx
  mov    $0x5,%esi
  mov    %r12,%rdi
  call   <changeByte@plt>
  mov    $0x0,%r8d
  mov    $0x1,%ecx
  mov    %rbx,%rdx
  mov    %r12,%rsi
  lea    D6(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  mov    $0x500000,%edx
  mov    %rbx,%rsi
  lea    D64(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbx,%rdi
  call   <blocksCount@plt>
  cmp    %rax,%rbp
  setle  %al
  movzbl %al,%eax
  add    %rax,%r13
  mov    $0x0,%edx
  mov    $0x5,%esi
  mov    %r12,%rdi
  call   <changeByte@plt>
  mov    $0x0,%r8d
  mov    $0x1,%ecx
  mov    %rbx,%rdx
  mov    %r12,%rsi
  lea    D55(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  mov    $0x500000,%edx
  mov    %rbx,%rsi
  lea    D178(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbx,%rdi
  call   <blocksCount@plt>
  cmp    %rax,%rbp
  setle  %al
  movzbl %al,%eax
  add    %rax,%r13
  mov    $0x0,%edx
  mov    $0x500000,%esi
  mov    %r12,%rdi
  call   <addBytes@plt>
  mov    %r12,%rdi
  call   <blocksCount@plt>
  mov    %rax,%rbx
  mov    $0x0,%r8d
  mov    $0x1,%ecx
  lea    D56(%rip),%rbp
  mov    %rbp,%rdx
  mov    %r12,%rsi
  lea    D81(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  mov    $0xa00000,%edx
  mov    %rbp,%rsi
  lea    D128(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbp,%rdi
  call   <blocksCount@plt>
  cmp    %rax,%rbx
  jg     L34
  mov    $0x63,%edx
  mov    $0x700000,%esi
  mov    %r12,%rdi
  call   <changeByte@plt>
  mov    $0x0,%r8d
  mov    $0x1,%ecx
  lea    D56(%rip),%rbx
  mov    %rbx,%rdx
  mov    %r12,%rsi
  lea    D110(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  mov    $0xa00000,%edx
  mov    %rbx,%rsi
  lea    D116(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbx,%rdi
  call   <blocksCount@plt>
L10:
  lea    D125(%rip),%rdi
  call   <printf@plt>
  jmp    L15
L34:
  mov    $0x63,%edx
  mov    $0x700000,%esi
  lea    D86(%rip),%r12
  mov    %r12,%rdi
  call   <changeByte@plt>
  mov    $0x0,%r8d
  mov    $0x1,%ecx
  lea    D56(%rip),%rbp
  mov    %rbp,%rdx
  mov    %r12,%rsi
  lea    D110(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  mov    $0xa00000,%edx
  mov    %rbp,%rsi
  lea    D116(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbp,%rdi
  call   <blocksCount@plt>
  cmp    %rax,%rbx
  jle    L10
  test   %r13,%r13
  jg     L10
L15:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
```

tool_calls: name: parse_data
arguments: label: D86
type: string
name: parse_data
arguments: label: D56
type: string
name: parse_data
arguments: label: D143
type: string
name: parse_data
arguments: label: D115
type: string
name: parse_data
arguments: label: D6
type: string
name: parse_data
arguments: label: D64
type: string
name: parse_data
arguments: label: D55
type: string
name: parse_data
arguments: label: D178
type: string
name: parse_data
arguments: label: D81
type: string
name: parse_data
arguments: label: D128
type: string
name: parse_data
arguments: label: D110
type: string
name: parse_data
arguments: label: D116
type: string
name: parse_data
arguments: label: D125
type: string

tool: D86: testSource.bin

tool: D56: testDest.bin

tool: D143: recreated source to zero

tool: D115: recreated source to zero size

tool: D6: changed byte (SPARSE) 

tool: D64: changed byte (SPARSE) (size)

tool: D55: changed byte to zero (SPARSE) 

tool: D178: changed byte to zero (SPARSE) (size)

tool: D81: added 5 md (SPARSE) 

tool: D128: added 5 md (SPARSE) (size)

tool: D110: changed one byte (SPARSE) 

tool: D116: changed one byte (SPARSE) (size)

tool: D125: 
  Warning: sparse mode was enabled, but the destination file doesn't seem
  to occupy less disk space then the original file. For certain file systems it's
  okay as they don't support sparse files.

  This warning is safe, sparse files support is NOT required for data integrity.



assistant: ```c
void testSparse() {
  cleanup();
  uint32_t sparseFailCount = 0;
  createZeroFile("testSource.bin", 1024 * 1024 * 5);
  uint32_t sourceBlocksCount = blocksCount("testSource.bin");
  syncAndCheckMd4("recreated source to zero", "testSource.bin", "testDest.bin", 1, 0);
  checkFileSize("recreated source to zero size", "testDest.bin", 1024 * 1024 * 5);
  uint32_t destBlocksCount = blocksCount("testDest.bin");
  if (destBlocksCount >= sourceBlocksCount) {
    sparseFailCount++;
  }
  changeByte("testSource.bin", 5, 'c');
  syncAndCheckMd4("changed byte (SPARSE) ", "testSource.bin", "testDest.bin", 1, 0);
  checkFileSize("changed byte (SPARSE) (size)", "testDest.bin", 1024 * 1024 * 5);
  destBlocksCount = blocksCount("testDest.bin");
  if (destBlocksCount >= sourceBlocksCount) {
    sparseFailCount++;
  }
  changeByte("testSource.bin", 5, 0);
  syncAndCheckMd4("changed byte to zero (SPARSE) ", "testSource.bin", "testDest.bin", 1, 0);
  checkFileSize("changed byte to zero (SPARSE) (size)", "testDest.bin", 1024 * 1024 * 5);
  destBlocksCount = blocksCount("testDest.bin");
  if (destBlocksCount >= sourceBlocksCount) {
    sparseFailCount++;
  }
  addBytes("testSource.bin", 5 * 1024 * 1024, 0);
  sourceBlocksCount = blocksCount("testSource.bin");
  syncAndCheckMd4("added 5 md (SPARSE) ", "testSource.bin", "testDest.bin", 1, 0);
  checkFileSize("added 5 md (SPARSE) (size)", "testDest.bin", 1024 * 1024 * 10);
  destBlocksCount = blocksCount("testDest.bin");
  if (destBlocksCount >= sourceBlocksCount) {
    sparseFailCount++;
  }
  changeByte("testSource.bin", 7 * 1024 * 1024, 'c');
  syncAndCheckMd4("changed one byte (SPARSE) ", "testSource.bin", "testDest.bin", 1, 0);
  checkFileSize("changed one byte (SPARSE) (size)", "testDest.bin", 1024 * 1024 * 10);
  destBlocksCount = blocksCount("testDest.bin");
  if (destBlocksCount >= sourceBlocksCount) {
    sparseFailCount++;
  }
  if (sparseFailCount > 0) {
    printf("\n  Warning: sparse mode was enabled, but the destination file doesn't seem\n"
           "  to occupy less disk space then the original file. For certain file systems it's\n"
           "  okay as they don't support sparse files.\n\n"
           "  This warning is safe, sparse files support is NOT required for data integrity.\n\n");
  }
}
```