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

```asm
<move_to_beginning>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %rcx,-0x50(%rbp)
  mov    %r8d,-0x54(%rbp)
  mov    -0x48(%rbp),%rax
  cmp    -0x40(%rbp),%rax
  setbe  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x50(%rbp),%rax
  cmp    -0x40(%rbp),%rax
  setbe  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  movq   $0x0,-0x30(%rbp)
  mov    -0x48(%rbp),%rdx
  mov    -0x50(%rbp),%rax
  add    %rdx,%rax
  mov    $0x0,%edx
  divq   -0x40(%rbp)
  mov    %rdx,-0x28(%rbp)
  jmp    L185
L277:
  cmpl   $0x0,-0x54(%rbp)
  je     L167
  movq   $0x0,-0x20(%rbp)
  jmp    L392
L308:
  mov    -0x20(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%eax
  mov    %eax,%esi
  lea    D17(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  addq   $0x1,-0x20(%rbp)
L392:
  mov    -0x20(%rbp),%rax
  cmp    -0x40(%rbp),%rax
  jb     L308
  mov    $0xa,%edi
  call   <putchar@plt>
  mov    -0x50(%rbp),%rsi
  mov    -0x28(%rbp),%rcx
  mov    -0x48(%rbp),%rdx
  mov    -0x30(%rbp),%rax
  mov    %rsi,%r8
  mov    %rax,%rsi
  lea    D77(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L167:
  mov    -0x30(%rbp),%rax
  cmp    -0x40(%rbp),%rax
  setb   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x30(%rbp),%rax
  cmp    -0x48(%rbp),%rax
  ja     L395
  mov    -0x48(%rbp),%rax
  cmp    -0x40(%rbp),%rax
  ja     L395
  mov    $0x1,%eax
  jmp    L178
L395:
  mov    $0x0,%eax
L178:
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x30(%rbp),%rax
  cmp    -0x28(%rbp),%rax
  ja     L159
  mov    -0x28(%rbp),%rax
  cmp    -0x40(%rbp),%rax
  ja     L159
  mov    $0x1,%eax
  jmp    L101
L159:
  mov    $0x0,%eax
L101:
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x48(%rbp),%rax
  cmp    -0x28(%rbp),%rax
  jbe    L260
  mov    -0x40(%rbp),%rax
  sub    -0x48(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x28(%rbp),%rax
  sub    -0x30(%rbp),%rax
  add    %rdx,%rax
  cmp    %rax,-0x50(%rbp)
  jne    L331
L260:
  mov    $0x1,%eax
  jmp    L43
L331:
  mov    $0x0,%eax
L43:
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x48(%rbp),%rax
  cmp    -0x28(%rbp),%rax
  jae    L12
  mov    -0x28(%rbp),%rax
  sub    -0x48(%rbp),%rax
  cmp    %rax,-0x50(%rbp)
  jne    L371
L12:
  mov    $0x1,%eax
  jmp    L191
L371:
  mov    $0x0,%eax
L191:
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x48(%rbp),%rax
  cmp    -0x28(%rbp),%rax
  jne    L28
  cmpq   $0x0,-0x50(%rbp)
  je     L28
  mov    -0x30(%rbp),%rdx
  mov    -0x50(%rbp),%rax
  add    %rdx,%rax
  cmp    %rax,-0x40(%rbp)
  jne    L381
L28:
  mov    $0x1,%eax
  jmp    L45
L381:
  mov    $0x0,%eax
L45:
  mov    %eax,%edi
  call   <assert@plt>
  cmpq   $0x0,-0x50(%rbp)
  je     L326
  mov    -0x48(%rbp),%rax
  cmp    -0x40(%rbp),%rax
  je     L326
  mov    -0x48(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jne    L304
L326:
  cmpl   $0x0,-0x54(%rbp)
  je     L133
  lea    D4(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  jmp    L133
L304:
  mov    -0x28(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jne    L234
  cmpl   $0x0,-0x54(%rbp)
  je     L363
  lea    D60(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  mov    -0x40(%rbp),%rax
  mov    %rax,%rsi
  lea    D81(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L363:
  mov    -0x40(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  jmp    L185
L234:
  mov    -0x48(%rbp),%rax
  cmp    -0x28(%rbp),%rax
  jae    L40
  cmpl   $0x0,-0x54(%rbp)
  je     L359
  lea    D86(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
L359:
  mov    -0x54(%rbp),%r8d
  mov    -0x50(%rbp),%rdi
  mov    -0x48(%rbp),%rcx
  mov    -0x30(%rbp),%rdx
  mov    -0x40(%rbp),%rsi
  mov    -0x38(%rbp),%rax
  mov    %r8d,%r9d
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <move_part@plt>
  jmp    L16
L40:
  mov    -0x28(%rbp),%rax
  sub    -0x30(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x40(%rbp),%rax
  sub    -0x48(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x10(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  cmp    %rax,-0x50(%rbp)
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x18(%rbp),%rax
  cmp    -0x10(%rbp),%rax
  jb     L257
  cmpl   $0x0,-0x54(%rbp)
  je     L23
  lea    D26(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
L23:
  mov    -0x54(%rbp),%r8d
  mov    -0x10(%rbp),%rdi
  mov    -0x48(%rbp),%rcx
  mov    -0x30(%rbp),%rdx
  mov    -0x40(%rbp),%rsi
  mov    -0x38(%rbp),%rax
  mov    %r8d,%r9d
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <swap_parts@plt>
  cmpq   $0x0,-0x10(%rbp)
  setne  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x10(%rbp),%rax
  add    %rax,-0x30(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  jmp    L185
L257:
  mov    -0x48(%rbp),%rax
  sub    -0x30(%rbp),%rax
  cmp    %rax,-0x10(%rbp)
  jb     L321
  mov    -0x48(%rbp),%rax
  sub    -0x30(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  cmp    -0x18(%rbp),%rax
  setae  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  cmpl   $0x0,-0x54(%rbp)
  je     L347
  lea    D51(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
L347:
  mov    -0x54(%rbp),%r8d
  mov    -0x18(%rbp),%rdi
  mov    -0x48(%rbp),%rcx
  mov    -0x30(%rbp),%rdx
  mov    -0x40(%rbp),%rsi
  mov    -0x38(%rbp),%rax
  mov    %r8d,%r9d
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <swap_parts@plt>
  mov    -0x48(%rbp),%rax
  sub    -0x28(%rbp),%rax
  mov    %rax,%rdi
  mov    -0x48(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x54(%rbp),%r8d
  mov    -0x28(%rbp),%rdx
  mov    -0x40(%rbp),%rsi
  mov    -0x38(%rbp),%rax
  mov    %r8d,%r9d
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <move_part@plt>
  mov    -0x48(%rbp),%rax
  sub    -0x28(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  cmp    %rax,-0x8(%rbp)
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x8(%rbp),%rax
  sub    %rax,-0x50(%rbp)
  mov    -0x48(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x8(%rbp),%rax
  add    %rax,-0x48(%rbp)
  mov    -0x8(%rbp),%rax
  add    %rax,-0x28(%rbp)
  jmp    L185
L321:
  mov    -0x18(%rbp),%rax
  cmp    -0x10(%rbp),%rax
  ja     L118
  cmpl   $0x0,-0x54(%rbp)
  je     L232
  lea    D72(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
L232:
  mov    -0x54(%rbp),%r8d
  mov    -0x18(%rbp),%rdi
  mov    -0x48(%rbp),%rcx
  mov    -0x30(%rbp),%rdx
  mov    -0x40(%rbp),%rsi
  mov    -0x38(%rbp),%rax
  mov    %r8d,%r9d
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <swap_parts@plt>
  mov    -0x10(%rbp),%rax
  sub    -0x18(%rbp),%rax
  mov    %rax,%rdi
  mov    -0x48(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x54(%rbp),%r8d
  mov    -0x28(%rbp),%rdx
  mov    -0x40(%rbp),%rsi
  mov    -0x38(%rbp),%rax
  mov    %r8d,%r9d
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <move_part@plt>
  mov    -0x10(%rbp),%rax
  add    %rax,-0x30(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x48(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x28(%rbp)
  jmp    L185
L118:
  mov    $0x0,%edi
  call   <assert@plt>
L185:
  mov    -0x30(%rbp),%rax
  cmp    -0x40(%rbp),%rax
  jne    L277
  jmp    L16
L133:
  nop
L16:
  nop
  leave
  ret
```

tool_calls: name: extract_symbolic_data
arguments: label: D17
type_infered: string
name: extract_symbolic_data
arguments: label: D77
type_infered: string
name: extract_symbolic_data
arguments: label: D4
type_infered: string
name: extract_symbolic_data
arguments: label: D60
type_infered: string
name: extract_symbolic_data
arguments: label: D81
type_infered: string
name: extract_symbolic_data
arguments: label: D86
type_infered: string
name: extract_symbolic_data
arguments: label: D26
type_infered: string
name: extract_symbolic_data
arguments: label: D51
type_infered: string
name: extract_symbolic_data
arguments: label: D72
type_infered: string

tool: D17: %d 

tool: D77: part_start %d  begin %d  end %d  size %d


tool: D4: Case 1:
Terminating

tool: D60: Case 2:

tool: D81: Setting end to %d.


tool: D86: Case 3:

tool: D26: Case 4:

tool: D51: Case 5

tool: D72: Case 6

assistant: ```c
void move_to_beginning(int *A, size_t N, size_t begin, size_t size, int show_steps) {
  assert(begin <= N);
  assert(size <= N);
  size_t part_start = 0;
  size_t end = (begin + size) % N;
  while (part_start != N) {
    size_t i;
    if (show_steps) {
      for (i = 0; i < N; ++i) {
        printf("%d ", A[i]);
      }
      printf("\n");
      printf("part_start %d  begin %d  end %d  size %d\n", part_start, begin, end, size);
    }
    assert(part_start < N);
    assert(part_start <= begin && begin <= N);
    assert(part_start <= end && end <= N);
    assert(begin <= end || (N - begin) + (end - part_start) == size);
    assert(begin >= end || end - begin == size);
    assert(begin != end || size == 0 || part_start + size == N);
    if (size == 0 || begin == N || begin == part_start) {
      if (show_steps) {
        printf("Case 1:\nTerminating\n");
      }
      break;
    } else if (end == part_start) {
      if (show_steps) {
        printf("Case 2:\n");
        printf("Setting end to %d.\n", N);
      }
      end = N;
    } else if (begin < end) {
      if (show_steps) {
        printf("Case 3:\n");
      }
      move_part(A, N, part_start, begin, size, show_steps);
      break;
    } else {
      size_t end_size = end - part_start;
      size_t begin_size = N - begin;
      assert(begin_size + end_size == size);
      if (end_size >= begin_size) {
        if (show_steps) {
          printf("Case 4:\n");
        }
        swap_parts(A, N, part_start, begin, begin_size, show_steps);
        assert(begin_size > 0);
        part_start += begin_size;
        size = end_size;
      } else if (begin - part_start <= begin_size) {
        size_t size_moved = begin - part_start;
        assert(size_moved >= end_size);
        if (show_steps) {
          printf("Case 5\n");
        }
        swap_parts(A, N, part_start, begin, end_size, show_steps);
        move_part(A, N, end, begin + end_size, begin - end, show_steps);
        assert(end_size + (begin - end) == size_moved);
        size -= size_moved;
        part_start = begin;
        begin += size_moved;
        end += size_moved;
      } else if (end_size <= begin_size) {
        if (show_steps) {
          printf("Case 6\n");
        }
        swap_parts(A, N, part_start, begin, end_size, show_steps);
        move_part(A, N, end, begin + end_size, begin_size - end_size, show_steps);
        part_start += begin_size;
        size = end_size;
        end = begin + end_size;
      } else {
        assert(0);
      }
    }
  }
}
```