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

```asm
<aes_mixColumns_inv>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbx
  sub    $0x18,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    $0x0,%ebx
  jmp    L2
L0:
  movzbl %bl,%edx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%r15d
  movzbl %bl,%eax
  lea    0x1(%rax),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%r13d
  movzbl %bl,%eax
  lea    0x2(%rax),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%r12d
  movzbl %bl,%eax
  lea    0x3(%rax),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%esi
  mov    %r15d,%eax
  xor    %r13d,%eax
  xor    %r12d,%eax
  mov    %sil,-0x39(%rbp)
  xor    -0x39(%rbp),%al
  mov    %eax,%r14d
  movzbl %r14b,%eax
  mov    %eax,%edi
  call   <rj_xtime@plt>
  mov    %al,-0x3b(%rbp)
  xor    %r15d,%eax
  xor    %r12d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <rj_xtime@plt>
  movzbl %al,%eax
  mov    %eax,%edi
  call   <rj_xtime@plt>
  mov    %eax,%edi
  xor    %r14d,%edi
  mov    %dil,-0x3a(%rbp)
  movzbl -0x3b(%rbp),%eax
  xor    %r13d,%eax
  xor    -0x39(%rbp),%al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <rj_xtime@plt>
  movzbl %al,%eax
  mov    %eax,%edi
  call   <rj_xtime@plt>
  xor    %eax,%r14d
  mov    %r15d,%eax
  xor    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <rj_xtime@plt>
  xor    -0x3a(%rbp),%al
  movzbl %al,%edx
  movzbl %bl,%ecx
  mov    -0x38(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  xor    %eax,%ecx
  movzbl %bl,%edx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  mov    %r13d,%eax
  xor    %r12d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <rj_xtime@plt>
  xor    %r14d,%eax
  movzbl %al,%edx
  movzbl %bl,%eax
  lea    0x1(%rax),%rcx
  mov    -0x38(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  xor    %eax,%ecx
  mov    %ecx,%edx
  movzbl %bl,%eax
  lea    0x1(%rax),%rcx
  mov    -0x38(%rbp),%rax
  add    %rcx,%rax
  mov    %dl,(%rax)
  mov    %r12d,%eax
  movzbl -0x39(%rbp),%r13d
  xor    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <rj_xtime@plt>
  xor    -0x3a(%rbp),%al
  movzbl %al,%edx
  movzbl %bl,%eax
  lea    0x2(%rax),%rcx
  mov    -0x38(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  xor    %eax,%ecx
  mov    %ecx,%edx
  movzbl %bl,%eax
  lea    0x2(%rax),%rcx
  mov    -0x38(%rbp),%rax
  add    %rcx,%rax
  mov    %dl,(%rax)
  mov    %r13d,%eax
  xor    %r15d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <rj_xtime@plt>
  xor    %r14d,%eax
  movzbl %al,%edx
  movzbl %bl,%eax
  lea    0x3(%rax),%rcx
  mov    -0x38(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  xor    %eax,%ecx
  mov    %ecx,%edx
  movzbl %bl,%eax
  lea    0x3(%rax),%rcx
  mov    -0x38(%rbp),%rax
  add    %rcx,%rax
  mov    %dl,(%rax)
  add    $0x4,%ebx
L2:
  cmp    $0xf,%bl
  jbe    L0
  nop
  nop
  add    $0x18,%rsp
  pop    %rbx
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  pop    %rbp
  ret
```

assistant: ```c
void aes_mixColumns_inv(unsigned char *buf) {
  register unsigned char i, a, b, c, d, e, x, y, z;
  for (i = 0; i < 16; i += 4) {
    a = buf[i];
    b = buf[i + 1];
    c = buf[i + 2];
    d = buf[i + 3];
    e = a ^ b ^ c ^ d;
    z = rj_xtime(e);
    x = e ^ rj_xtime(rj_xtime(z ^ a ^ c));
    y = e ^ rj_xtime(rj_xtime(z ^ b ^ d));
    buf[i] ^= x ^ rj_xtime(a ^ b);
    buf[i + 1] ^= y ^ rj_xtime(b ^ c);
    buf[i + 2] ^= x ^ rj_xtime(c ^ d);
    buf[i + 3] ^= y ^ rj_xtime(d ^ a);
  }
}
```