user: Translate the below assembly code into C programming language:

```asm
<xor_8regs_3>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    %rcx,-0x30(%rbp)
  mov    -0x18(%rbp),%rax
  shr    $0x6,%rax
  mov    %rax,-0x8(%rbp)
L6:
  mov    -0x20(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x28(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rax
  xor    %rcx,%rax
  xor    %rax,%rdx
  mov    -0x20(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x20(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%rcx
  mov    -0x30(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%rax
  xor    %rax,%rcx
  mov    -0x20(%rbp),%rax
  add    $0x8,%rax
  xor    %rcx,%rdx
  mov    %rdx,(%rax)
  mov    -0x20(%rbp),%rax
  add    $0x10,%rax
  mov    (%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    $0x10,%rax
  mov    (%rax),%rcx
  mov    -0x30(%rbp),%rax
  add    $0x10,%rax
  mov    (%rax),%rax
  xor    %rax,%rcx
  mov    -0x20(%rbp),%rax
  add    $0x10,%rax
  xor    %rcx,%rdx
  mov    %rdx,(%rax)
  mov    -0x20(%rbp),%rax
  add    $0x18,%rax
  mov    (%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    $0x18,%rax
  mov    (%rax),%rcx
  mov    -0x30(%rbp),%rax
  add    $0x18,%rax
  mov    (%rax),%rax
  xor    %rax,%rcx
  mov    -0x20(%rbp),%rax
  add    $0x18,%rax
  xor    %rcx,%rdx
  mov    %rdx,(%rax)
  mov    -0x20(%rbp),%rax
  add    $0x20,%rax
  mov    (%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    $0x20,%rax
  mov    (%rax),%rcx
  mov    -0x30(%rbp),%rax
  add    $0x20,%rax
  mov    (%rax),%rax
  xor    %rax,%rcx
  mov    -0x20(%rbp),%rax
  add    $0x20,%rax
  xor    %rcx,%rdx
  mov    %rdx,(%rax)
  mov    -0x20(%rbp),%rax
  add    $0x28,%rax
  mov    (%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    $0x28,%rax
  mov    (%rax),%rcx
  mov    -0x30(%rbp),%rax
  add    $0x28,%rax
  mov    (%rax),%rax
  xor    %rax,%rcx
  mov    -0x20(%rbp),%rax
  add    $0x28,%rax
  xor    %rcx,%rdx
  mov    %rdx,(%rax)
  mov    -0x20(%rbp),%rax
  add    $0x30,%rax
  mov    (%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    $0x30,%rax
  mov    (%rax),%rcx
  mov    -0x30(%rbp),%rax
  add    $0x30,%rax
  mov    (%rax),%rax
  xor    %rax,%rcx
  mov    -0x20(%rbp),%rax
  add    $0x30,%rax
  xor    %rcx,%rdx
  mov    %rdx,(%rax)
  mov    -0x20(%rbp),%rax
  add    $0x38,%rax
  mov    (%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    $0x38,%rax
  mov    (%rax),%rcx
  mov    -0x30(%rbp),%rax
  add    $0x38,%rax
  mov    (%rax),%rax
  xor    %rax,%rcx
  mov    -0x20(%rbp),%rax
  add    $0x38,%rax
  xor    %rcx,%rdx
  mov    %rdx,(%rax)
  addq   $0x40,-0x20(%rbp)
  addq   $0x40,-0x28(%rbp)
  addq   $0x40,-0x30(%rbp)
  subq   $0x1,-0x8(%rbp)
  cmpq   $0x0,-0x8(%rbp)
  jg     L6
  nop
  nop
  pop    %rbp
  ret
```

assistant: ```c
void xor_8regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, unsigned long *p3) {
  long lines = bytes / (sizeof(long)) / 8;
  do {
    p1[0] ^= p2[0] ^ p3[0];
    p1[1] ^= p2[1] ^ p3[1];
    p1[2] ^= p2[2] ^ p3[2];
    p1[3] ^= p2[3] ^ p3[3];
    p1[4] ^= p2[4] ^ p3[4];
    p1[5] ^= p2[5] ^ p3[5];
    p1[6] ^= p2[6] ^ p3[6];
    p1[7] ^= p2[7] ^ p3[7];
    p1 += 8;
    p2 += 8;
    p3 += 8;
  } while (--lines > 0);
}
```