user: Converte this assembly snippet into its equivalent C code:

```asm
<testSparse>:
  endbr64
  push   %r13
  xor    %eax,%eax
  xor    %r13d,%r13d
  push   %r12
  lea    D114(%rip),%r12
  push   %rbp
  lea    D40(%rip),%rbp
  push   %rbx
  sub    $0x8,%rsp
  call   <cleanup@plt>
  mov    $0x500000,%esi
  mov    %r12,%rdi
  call   <createZeroFile@plt>
  mov    %r12,%rdi
  call   <blocksCount@plt>
  xor    %r8d,%r8d
  mov    $0x1,%ecx
  mov    %rbp,%rdx
  mov    %r12,%rsi
  lea    D89(%rip),%rdi
  mov    %rax,%rbx
  call   <syncAndCheckMd4@plt>
  mov    $0x500000,%edx
  mov    %rbp,%rsi
  lea    D44(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbp,%rdi
  call   <blocksCount@plt>
  mov    $0x63,%edx
  mov    $0x5,%esi
  mov    %r12,%rdi
  cmp    %rax,%rbx
  setle  %r13b
  call   <changeByte@plt>
  xor    %r8d,%r8d
  mov    $0x1,%ecx
  mov    %rbp,%rdx
  mov    %r12,%rsi
  lea    D21(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  mov    $0x500000,%edx
  mov    %rbp,%rsi
  lea    D124(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbp,%rdi
  call   <blocksCount@plt>
  mov    $0x5,%esi
  mov    %r12,%rdi
  cmp    %rax,%rbx
  setle  %al
  xor    %edx,%edx
  movzbl %al,%eax
  add    %rax,%r13
  call   <changeByte@plt>
  xor    %r8d,%r8d
  mov    $0x1,%ecx
  mov    %rbp,%rdx
  mov    %r12,%rsi
  lea    D123(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  mov    $0x500000,%edx
  mov    %rbp,%rsi
  lea    D20(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbp,%rdi
  call   <blocksCount@plt>
  mov    $0x500000,%esi
  mov    %r12,%rdi
  cmp    %rax,%rbx
  setle  %al
  xor    %edx,%edx
  movzbl %al,%eax
  add    %rax,%r13
  call   <addBytes@plt>
  mov    %r12,%rdi
  call   <blocksCount@plt>
  xor    %r8d,%r8d
  mov    $0x1,%ecx
  mov    %rbp,%rdx
  mov    %r12,%rsi
  lea    D1(%rip),%rdi
  mov    %rax,%rbx
  call   <syncAndCheckMd4@plt>
  mov    $0xa00000,%edx
  mov    %rbp,%rsi
  lea    D101(%rip),%rdi
  call   <checkFileSize@plt>
  mov    %rbp,%rdi
  call   <blocksCount@plt>
  mov    $0x63,%edx
  mov    $0x700000,%esi
  mov    %r12,%rdi
  cmp    %rax,%rbx
  jg     L14
  call   <changeByte@plt>
  xor    %r8d,%r8d
  mov    $0x1,%ecx
  mov    %rbp,%rdx
  mov    %r12,%rsi
  lea    D134(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  lea    D110(%rip),%rdi
  mov    $0xa00000,%edx
  mov    %rbp,%rsi
  call   <checkFileSize@plt>
  mov    %rbp,%rdi
  call   <blocksCount@plt>
L26:
  add    $0x8,%rsp
  lea    D39(%rip),%rdi
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  jmp    10d0 <printf@plt>
  nopl   0x0(%rax,%rax,1)
L14:
  call   <changeByte@plt>
  xor    %r8d,%r8d
  mov    $0x1,%ecx
  mov    %rbp,%rdx
  mov    %r12,%rsi
  lea    D134(%rip),%rdi
  call   <syncAndCheckMd4@plt>
  lea    D110(%rip),%rdi
  mov    $0xa00000,%edx
  mov    %rbp,%rsi
  call   <checkFileSize@plt>
  mov    %rbp,%rdi
  call   <blocksCount@plt>
  cmp    %rax,%rbx
  jle    L26
  test   %r13,%r13
  jne    L26
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
```

tool_calls: name: retrieve_data
arguments: data_tag: D114
data_type: string
name: retrieve_data
arguments: data_tag: D40
data_type: string
name: retrieve_data
arguments: data_tag: D89
data_type: string
name: retrieve_data
arguments: data_tag: D44
data_type: string
name: retrieve_data
arguments: data_tag: D21
data_type: string
name: retrieve_data
arguments: data_tag: D124
data_type: string
name: retrieve_data
arguments: data_tag: D123
data_type: string
name: retrieve_data
arguments: data_tag: D20
data_type: string
name: retrieve_data
arguments: data_tag: D1
data_type: string
name: retrieve_data
arguments: data_tag: D101
data_type: string
name: retrieve_data
arguments: data_tag: D134
data_type: string
name: retrieve_data
arguments: data_tag: D110
data_type: string
name: retrieve_data
arguments: data_tag: D39
data_type: string

tool: D114: testSource.bin

tool: D40: testDest.bin

tool: D89: recreated source to zero

tool: D44: recreated source to zero size

tool: D21: changed byte (SPARSE) 

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

tool: D123: changed byte to zero (SPARSE) 

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

tool: D1: added 5 md (SPARSE) 

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

tool: D134: changed one byte (SPARSE) 

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

tool: D39: 
  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");
  }
}
```