user: 请从给定的汇编指令推导出C源代码：

```asm
<main>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  call   <test_init@plt>
  lea    D90(%rip),%rdi
  call   <getenv@plt>
  lea    D8(%rip),%rdi
  test   %rax,%rax
  mov    %rax,%rbx
  setne  %r13b
  call   <getenv@plt>
  lea    D91(%rip),%rdi
  mov    %rax,%r12
  call   <getenv@plt>
  test   %rax,%rax
  je     L49
  mov    %rax,%rdi
  lea    D99(%rip),%rsi
  call   <strstr@plt>
  test   %rax,%rax
  je     L49
  mov    $0x2000000,%edi
  mov    $0x1,%r15d
  call   <malloc@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  je     L85
L32:
  xor    %esi,%esi
  mov    %rbp,%rdi
  mov    $0x2000000,%edx
  call   <memset@plt>
  lea    0x1ffffff(%rbp),%r14
  mov    %r14,%rdi
  call   <test_addr_huge@plt>
  cmp    $0x1,%eax
  je     L33
  test   %r13b,%r13b
  je     L33
  test   %r12,%r12
  je     L76
  test   %r15d,%r15d
  je     L76
  lea    D86(%rip),%r15
L121:
  xor    %eax,%eax
  call   <cleanup@plt>
  mov    %r15,%rdi
  call   <puts@plt>
  xor    %edi,%edi
  call   <exit@plt>
  mov    %rbp,%rdi
  call   <free@plt>
L58:
  mov    %r14,%rdi
  call   <test_addr_huge@plt>
  sub    $0x1,%eax
  jne    L150
  xor    %eax,%eax
  call   <cleanup@plt>
  lea    D1(%rip),%rdi
  call   <puts@plt>
  mov    $0x2,%edi
  call   <exit@plt>
  jmp    L150
L49:
  mov    $0x2000000,%edi
  call   <malloc@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  je     L42
  xor    %esi,%esi
  mov    %rax,%rdi
  mov    $0x2000000,%edx
  call   <memset@plt>
  lea    0x1ffffff(%rbp),%r14
  mov    %r14,%rdi
  call   <test_addr_huge@plt>
  cmp    $0x1,%eax
  je     L33
  test   %r13b,%r13b
  je     L33
L76:
  xor    %eax,%eax
  call   <cleanup@plt>
  lea    D96(%rip),%rdi
  call   <puts@plt>
  mov    $0x2,%edi
  call   <exit@plt>
L90:
  mov    %rbp,%rdi
  call   <free@plt>
  test   %r12,%r12
  jne    L58
L150:
  xor    %eax,%eax
  call   <cleanup@plt>
  lea    D98(%rip),%rdi
  call   <puts@plt>
  xor    %edi,%edi
  call   <exit@plt>
  add    $0x8,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L33:
  sub    $0x1,%eax
  sete   %al
  test   %rbx,%rbx
  jne    L90
  test   %al,%al
  je     L90
L227:
  xor    %eax,%eax
  call   <cleanup@plt>
  lea    D35(%rip),%rdi
  call   <puts@plt>
  mov    $0x2,%edi
  call   <exit@plt>
  jmp    L90
L42:
  xor    %r15d,%r15d
L8:
  xor    %eax,%eax
  xor    %ebp,%ebp
  call   <cleanup@plt>
  mov    $0x2000000,%esi
  lea    D7(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  mov    $0x2,%edi
  call   <exit@plt>
  jmp    L32
L85:
  test   %r12,%r12
  je     L8
  xor    %eax,%eax
  lea    D86(%rip),%r15
  call   <cleanup@plt>
  mov    %r15,%rdi
  call   <puts@plt>
  xor    %edi,%edi
  call   <exit@plt>
  xor    %edi,%edi
  xor    %esi,%esi
  mov    $0x2000000,%edx
  call   <memset@plt>
  mov    $0x1ffffff,%edi
  call   <test_addr_huge@plt>
  cmp    $0x1,%eax
  je     L157
  mov    $0x1ffffff,%r14d
  test   %r13b,%r13b
  jne    L121
L157:
  test   %rbx,%rbx
  jne    L107
  sub    $0x1,%eax
  mov    $0x1ffffff,%r14d
  je     L227
L107:
  xor    %edi,%edi
  mov    $0x1ffffff,%r14d
  call   <free@plt>
  jmp    L58
```

tool_calls: name: unpack_data
arguments: data_label: D90
type_infered: string
name: unpack_data
arguments: data_label: D8
type_infered: string
name: unpack_data
arguments: data_label: D91
type_infered: string
name: unpack_data
arguments: data_label: D99
type_infered: string
name: unpack_data
arguments: data_label: D86
type_infered: string
name: unpack_data
arguments: data_label: D1
type_infered: string
name: unpack_data
arguments: data_label: D96
type_infered: string
name: unpack_data
arguments: data_label: D98
type_infered: string
name: unpack_data
arguments: data_label: D35
type_infered: string
name: unpack_data
arguments: data_label: D7
type_infered: string

tool: D90: HUGETLB_MORECORE

tool: D8: HUGETLB_MORECORE_SHRINK

tool: D91: LD_PRELOAD

tool: D99: heapshrink

tool: D86: PASS (inconclusive)

tool: D1: FAIL	Heap did not shrink

tool: D96: FAIL	Heap not on hugepages

tool: D98: PASS

tool: D35: FAIL	Heap unexpectedly on hugepages

tool: D7: FAIL	malloc(%d) failed



assistant: ```c
int main(int argc, char **argv) {
  int is_huge, have_env, shrink_ok, have_helper;
  void *p;
  test_init(argc, argv);
  have_env = getenv("HUGETLB_MORECORE") != NULL;
  shrink_ok = getenv("HUGETLB_MORECORE_SHRINK") != NULL;
  p = getenv("LD_PRELOAD");
  have_helper = p != NULL && strstr(p, "heapshrink") != NULL;
  p = malloc((32 * 1024 * 1024));
  if (!p) {
    if (shrink_ok && have_helper) {
      do {
        cleanup();
        printf("PASS (inconclusive)\n");
        exit(0);
      } while (0);
    } else
      do {
        cleanup();
        printf("FAIL\t"
               "malloc(%d) failed\n"
               "\n",
               (32 * 1024 * 1024));
        exit(2);
      } while (0);
  }
  memset(p, 0, (32 * 1024 * 1024));
  is_huge = test_addr_huge(p + (32 * 1024 * 1024) - 1) == 1;
  if (have_env && !is_huge) {
    if (shrink_ok && have_helper) {
      do {
        cleanup();
        printf("PASS (inconclusive)\n");
        exit(0);
      } while (0);
    } else
      do {
        cleanup();
        printf("FAIL\t"
               "Heap not on hugepages"
               "\n");
        exit(2);
      } while (0);
  }
  if (!have_env && is_huge)
    do {
      cleanup();
      printf("FAIL\t"
             "Heap unexpectedly on hugepages"
             "\n");
      exit(2);
    } while (0);
  free(p);
  if (shrink_ok && test_addr_huge(p + (32 * 1024 * 1024) - 1) == 1)
    do {
      cleanup();
      printf("FAIL\t"
             "Heap did not shrink"
             "\n");
      exit(2);
    } while (0);
  do {
    cleanup();
    printf("PASS\n");
    exit(0);
  } while (0);
}
```