user: 请显示与下面列出的汇编代码相匹配的C语言实现:

```asm
<aes_rcon_prev>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x18(%rbp)
  mov    %esi,-0x1c(%rbp)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L4
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x1(%rbp)
  mov    -0x18(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %eax,%edx
  movzbl -0x1(%rbp),%eax
  shr    %al
  xor    -0x1(%rbp),%al
  and    $0x1,%eax
  or     %edx,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %eax,%edx
  movzbl -0x1(%rbp),%eax
  shr    $0x2,%al
  movzbl %al,%eax
  add    %eax,%eax
  and    $0x2,%eax
  or     %edx,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %eax,%edx
  movzbl -0x1(%rbp),%eax
  shr    $0x3,%al
  xor    -0x1(%rbp),%al
  movzbl %al,%eax
  shl    $0x2,%eax
  and    $0x4,%eax
  or     %edx,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %eax,%edx
  movzbl -0x1(%rbp),%eax
  shr    $0x4,%al
  xor    -0x1(%rbp),%al
  movzbl %al,%eax
  shl    $0x3,%eax
  and    $0x8,%eax
  or     %edx,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %eax,%edx
  movzbl -0x1(%rbp),%eax
  shr    $0x5,%al
  movzbl %al,%eax
  shl    $0x4,%eax
  and    $0x10,%eax
  or     %edx,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %eax,%edx
  movzbl -0x1(%rbp),%eax
  shr    $0x6,%al
  movzbl %al,%eax
  shl    $0x5,%eax
  and    $0x20,%eax
  or     %edx,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %eax,%edx
  movzbl -0x1(%rbp),%eax
  shr    $0x7,%al
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0x40,%eax
  or     %edx,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %eax,%edx
  movzbl -0x1(%rbp),%eax
  shl    $0x7,%eax
  or     %edx,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %dl,(%rax)
  jmp    L17
L4:
  cmpl   $0x10,-0x1c(%rbp)
  jne    L8
  mov    -0x18(%rbp),%rax
  movb   $0x36,(%rax)
  jmp    L17
L8:
  cmpl   $0x18,-0x1c(%rbp)
  jne    L51
  mov    -0x18(%rbp),%rax
  movb   $0x80,(%rax)
  jmp    L17
L51:
  mov    -0x18(%rbp),%rax
  movb   $0x40,(%rax)
  nop
L17:
  pop    %rbp
  ret
```

assistant: ```c
void aes_rcon_prev(unsigned char *rcon, int key_len) {
  unsigned char rcon_tmp;
  if (*rcon) {
    rcon_tmp = *rcon;
    *rcon = 0x0;
    *rcon |= (((rcon_tmp >> 1) & 0x1) ^ ((rcon_tmp >> 0) & 0x1)) << 0;
    *rcon |= (((rcon_tmp >> 2) & 0x1)) << 1;
    *rcon |= (((rcon_tmp >> 3) & 0x1) ^ ((rcon_tmp >> 0) & 0x1)) << 2;
    *rcon |= (((rcon_tmp >> 4) & 0x1) ^ ((rcon_tmp >> 0) & 0x1)) << 3;
    *rcon |= (((rcon_tmp >> 5) & 0x1)) << 4;
    *rcon |= (((rcon_tmp >> 6) & 0x1)) << 5;
    *rcon |= (((rcon_tmp >> 7) & 0x1)) << 6;
    *rcon |= (((rcon_tmp >> 0) & 0x1)) << 7;
  } else {
    if (key_len == 16) {
      *rcon = 0x36;
    } else if (key_len == 24) {
      *rcon = 0x80;
    } else {
      *rcon = 0x40;
    }
  }
  return;
}
```