user: 请将以下的汇编代码转换成C语言代码:

```asm
<flash_unlock_block>:
  endbr64
  push   %rbx
  sub    $0x110,%rsp
  mov    %rdi,%r8
  mov    %esi,%r9d
  mov    %edx,%r10d
  mov    %fs:0x28,%rax
  mov    %rax,0x108(%rsp)
  xor    %eax,%eax
  mov    %edi,%eax
  and    $0xff800000,%eax
  cmp    $0xfff,%eax
  ja     L37
  mov    $0xd0000000,%eax
  movw   $0x50,(%rax)
  and    $0xff800000,%edi
  mov    %rax,%rcx
  test   %edx,%edx
  jle    L125
L67:
  mov    %rdi,%rax
  mov    $0x0,%edx
  mov    $0x0,%ebx
  movslq %r9d,%r11
  and    $0xfffffffffffffffe,%r11
  jmp    L189
L37:
  mov    %rdi,%rcx
  and    $0xff800000,%ecx
  movw   $0x50,(%rcx)
  mov    %rcx,%rdi
  test   %edx,%edx
  jg     L67
L18:
  mov    %r8d,%r8d
  jmp    L136
L117:
  mov    %eax,%esi
  movw   $0x98,(%eax)
  add    $0x4,%rsi
L156:
  movzwl (%rsi),%esi
L66:
  mov    %si,(%rsp,%rdx,2)
  add    %r11,%rax
  add    $0x1,%rdx
  cmp    %edx,%r10d
  jle    L125
L189:
  mov    %ebx,%esi
  cmp    %rax,%r8
  je     L66
  cmp    $0xfff,%eax
  ja     L117
  mov    %eax,%esi
  or     $0xd0000000,%esi
  movw   $0x98,(%esi)
  lea    0x4(%rsi),%esi
  jmp    L156
L125:
  cmp    $0xfff,%r8d
  ja     L18
  or     $0xd0000000,%r8d
L136:
  movb   $0x60,(%r8)
  movb   $0xd0,(%r8)
  mov    $0x4c4b40,%edx
L121:
  movzwl (%rcx),%eax
  test   $0x80,%al
  jne    L144
  sub    $0x1,%edx
  jne    L121
  jmp    L185
L144:
  test   %r10d,%r10d
  jle    L185
  mov    %rsp,%rsi
  lea    -0x1(%r10),%edx
  lea    0x2(%rsp,%rdx,2),%r8
  movslq %r9d,%r9
  and    $0xfffffffffffffffe,%r9
  jmp    L152
L128:
  add    %r9,%rdi
  add    $0x2,%rsi
  cmp    %r8,%rsi
  je     L185
L152:
  cmpw   $0x0,(%rsi)
  je     L128
  mov    %edi,%edx
  or     $0xd0000000,%edx
  mov    %edi,%eax
  cmp    $0xfff,%edi
  cmovbe %rdx,%rax
  movb   $0x60,(%rax)
  movb   $0x1,(%rax)
  mov    $0x4c4b40,%edx
L88:
  movzwl (%rcx),%eax
  test   $0x80,%al
  jne    L128
  sub    $0x1,%edx
  jne    L88
L185:
  movw   $0xff,(%rcx)
  movzwl %ax,%eax
  mov    0x108(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L91
  add    $0x110,%rsp
  pop    %rbx
  ret
L91:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int flash_unlock_block(volatile unsigned char *block, int block_size, int blocks) {
  volatile unsigned short *ROM, *bp;
  unsigned short stat;
  int timeout = 5000000;
  unsigned short is_locked[128];
  int i;
  ROM = (unsigned short *)((volatile unsigned char *)(((unsigned)((unsigned long)block & 0xFF800000) < 0x1000) ? ((unsigned)((unsigned long)block & 0xFF800000) | 0xd0000000) : (unsigned)((unsigned long)block & 0xFF800000)));
  ROM[0] = 0x50;
  bp = (unsigned short *)((unsigned long)block & 0xFF800000);
  for (i = 0; i < blocks; i++) {
    if (bp == (unsigned short *)block) {
      is_locked[i] = 0;
    } else {
      *(volatile unsigned short *)((volatile unsigned char *)(((unsigned)(bp) < 0x1000) ? ((unsigned)(bp) | 0xd0000000) : (unsigned)(bp))) = 0x98;
      is_locked[i] = ((volatile unsigned short *)((volatile unsigned char *)(((unsigned)(bp) < 0x1000) ? ((unsigned)(bp) | 0xd0000000) : (unsigned)(bp))))[2];
    }
    bp += block_size / sizeof(*bp);
  }
  ((volatile unsigned char *)(((unsigned)(block) < 0x1000) ? ((unsigned)(block) | 0xd0000000) : (unsigned)(block)))[0] = 0x60;
  ((volatile unsigned char *)(((unsigned)(block) < 0x1000) ? ((unsigned)(block) | 0xd0000000) : (unsigned)(block)))[0] = 0xD0;
  timeout = 5000000;
  while (((stat = ROM[0]) & 0x80) != 0x80) {
    if (--timeout == 0)
      goto done;
  }
  bp = (unsigned short *)((unsigned long)block & 0xFF800000);
  for (i = 0; i < blocks; i++) {
    if (is_locked[i]) {
      *((volatile unsigned char *)(((unsigned)(bp) < 0x1000) ? ((unsigned)(bp) | 0xd0000000) : (unsigned)(bp))) = 0x60;
      *((volatile unsigned char *)(((unsigned)(bp) < 0x1000) ? ((unsigned)(bp) | 0xd0000000) : (unsigned)(bp))) = 0x01;
      timeout = 5000000;
      while (((stat = ROM[0]) & 0x80) != 0x80) {
        if (--timeout == 0)
          goto done;
      }
    }
    bp += block_size / sizeof(*bp);
  }
done:
  ROM[0] = 0xFF;
  return stat;
}
```