user: What would the C source look like for the assembly code provided here?

```asm
<bn_sub_words>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    %ecx,-0x2c(%rbp)
  movl   $0x0,-0xc(%rbp)
  mov    -0x2c(%rbp),%eax
  not    %eax
  shr    $0x1f,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  cmpl   $0x0,-0x2c(%rbp)
  jg     L35
  mov    $0x0,%eax
  jmp    L55
L35:
  mov    -0x20(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  sub    -0x4(%rbp),%eax
  mov    -0xc(%rbp),%ecx
  sub    %ecx,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x8(%rbp),%eax
  cmp    -0x4(%rbp),%eax
  je     L139
  mov    -0x8(%rbp),%eax
  cmp    -0x4(%rbp),%eax
  setb   %al
  movzbl %al,%eax
  mov    %eax,-0xc(%rbp)
L139:
  subl   $0x1,-0x2c(%rbp)
  cmpl   $0x0,-0x2c(%rbp)
  jle    L52
  mov    -0x20(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  sub    -0x4(%rbp),%eax
  mov    %eax,%edx
  mov    -0xc(%rbp),%ecx
  mov    -0x18(%rbp),%rax
  add    $0x4,%rax
  sub    %ecx,%edx
  mov    %edx,(%rax)
  mov    -0x8(%rbp),%eax
  cmp    -0x4(%rbp),%eax
  je     L18
  mov    -0x8(%rbp),%eax
  cmp    -0x4(%rbp),%eax
  setb   %al
  movzbl %al,%eax
  mov    %eax,-0xc(%rbp)
L18:
  subl   $0x1,-0x2c(%rbp)
  cmpl   $0x0,-0x2c(%rbp)
  jle    L25
  mov    -0x20(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  sub    -0x4(%rbp),%eax
  mov    %eax,%edx
  mov    -0xc(%rbp),%ecx
  mov    -0x18(%rbp),%rax
  add    $0x8,%rax
  sub    %ecx,%edx
  mov    %edx,(%rax)
  mov    -0x8(%rbp),%eax
  cmp    -0x4(%rbp),%eax
  je     L26
  mov    -0x8(%rbp),%eax
  cmp    -0x4(%rbp),%eax
  setb   %al
  movzbl %al,%eax
  mov    %eax,-0xc(%rbp)
L26:
  subl   $0x1,-0x2c(%rbp)
  cmpl   $0x0,-0x2c(%rbp)
  jle    L61
  mov    -0x20(%rbp),%rax
  add    $0xc,%rax
  mov    (%rax),%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0xc,%rax
  mov    (%rax),%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  sub    -0x4(%rbp),%eax
  mov    %eax,%edx
  mov    -0xc(%rbp),%ecx
  mov    -0x18(%rbp),%rax
  add    $0xc,%rax
  sub    %ecx,%edx
  mov    %edx,(%rax)
  mov    -0x8(%rbp),%eax
  cmp    -0x4(%rbp),%eax
  je     L13
  mov    -0x8(%rbp),%eax
  cmp    -0x4(%rbp),%eax
  setb   %al
  movzbl %al,%eax
  mov    %eax,-0xc(%rbp)
L13:
  subl   $0x1,-0x2c(%rbp)
  cmpl   $0x0,-0x2c(%rbp)
  jle    L95
  addq   $0x10,-0x20(%rbp)
  addq   $0x10,-0x28(%rbp)
  addq   $0x10,-0x18(%rbp)
  jmp    L35
L52:
  nop
  jmp    L81
L25:
  nop
  jmp    L81
L61:
  nop
  jmp    L81
L95:
  nop
L81:
  mov    -0xc(%rbp),%eax
L55:
  leave
  ret
```

assistant: ```c
unsigned int bn_sub_words(unsigned int *r, const unsigned int *a, const unsigned int *b, int n) {
  unsigned int t1, t2;
  int c = 0;
  assert(n >= 0);
  if (n <= 0)
    return (unsigned int)0;
  for (;;) {
    t1 = a[0];
    t2 = b[0];
    r[0] = (t1 - t2 - c) & (0xffffffffL);
    if (t1 != t2)
      c = (t1 < t2);
    if (--n <= 0)
      break;
    t1 = a[1];
    t2 = b[1];
    r[1] = (t1 - t2 - c) & (0xffffffffL);
    if (t1 != t2)
      c = (t1 < t2);
    if (--n <= 0)
      break;
    t1 = a[2];
    t2 = b[2];
    r[2] = (t1 - t2 - c) & (0xffffffffL);
    if (t1 != t2)
      c = (t1 < t2);
    if (--n <= 0)
      break;
    t1 = a[3];
    t2 = b[3];
    r[3] = (t1 - t2 - c) & (0xffffffffL);
    if (t1 != t2)
      c = (t1 < t2);
    if (--n <= 0)
      break;
    a += 4;
    b += 4;
    r += 4;
  }
  return c;
}
```