user: 请从给定的汇编指令推导出C源代码：

```asm
<block_write>:
  endbr64
  push   %r12
  mov    %rsi,%r12
  push   %rbp
  mov    %edi,%ebp
  push   %rbx
  call   <unlock_block_for_writes@plt>
  mov    %ebp,%edi
  mov    $0xe8,%esi
  call   <flash_write@plt>
  mov    %ebp,%edi
  call   <flash_read@plt>
  test   $0x80,%al
  je     L44
L143:
  mov    $0x1f,%esi
  mov    %ebp,%edi
  xor    %ebx,%ebx
  call   <flash_write@plt>
  nopl   0x0(%rax,%rax,1)
L158:
  mov    (%r12,%rbx,4),%esi
  lea    0x0(%rbp,%rbx,1),%edi
  add    $0x1,%rbx
  call   <flash_write@plt>
  cmp    $0x20,%rbx
  jne    L158
  mov    %ebp,%edi
  mov    $0xd0,%esi
  call   <flash_write@plt>
  mov    %ebp,%edi
  call   <flash_read@plt>
  test   $0x80,%al
  jne    L29
  mov    $0xfff,%ebx
  jmp    L98
  nopl   (%rax)
L25:
  sub    $0x1,%ebx
  je     L99
L98:
  mov    %ebp,%edi
  call   <flash_read@plt>
  test   $0x80,%al
  je     L25
L29:
  mov    %ebp,%edi
  call   <flash_read_status@plt>
  mov    %eax,%r12d
  test   $0x8,%al
  jne    L127
L114:
  test   $0x30,%r12b
  jne    L64
L141:
  test   $0x2,%r12b
  jne    L43
L153:
  test   $0x20,%r12b
  jne    L135
L149:
  mov    %ebp,%edi
  call   <lock_block_to_prevent_writes@plt>
  pop    %rbx
  mov    %ebp,%edi
  pop    %rbp
  pop    %r12
  jmp    1100 <flash_read_mode@plt>
L44:
  lea    D54(%rip),%rdi
  xor    %eax,%eax
  call   <warnx@plt>
  jmp    L143
L135:
  lea    0x0(%rbp,%rbp,1),%esi
  mov    %r12d,%edx
  lea    D25(%rip),%rdi
  xor    %eax,%eax
  call   <warnx@plt>
  jmp    L149
L43:
  mov    %r12d,%esi
  lea    D28(%rip),%rdi
  xor    %eax,%eax
  call   <warnx@plt>
  jmp    L153
L64:
  mov    %r12d,%esi
  lea    D42(%rip),%rdi
  xor    %eax,%eax
  call   <warnx@plt>
  jmp    L141
L127:
  mov    %eax,%esi
  lea    D32(%rip),%rdi
  xor    %eax,%eax
  call   <warnx@plt>
  jmp    L114
L99:
  mov    $0xfff,%esi
  lea    D6(%rip),%rdi
  xor    %eax,%eax
  call   <warnx@plt>
  jmp    L29
```

tool_calls: name: parse_data
arguments: data_tag: D54
datatype: string
name: parse_data
arguments: data_tag: D25
datatype: string
name: parse_data
arguments: data_tag: D28
datatype: string
name: parse_data
arguments: data_tag: D42
datatype: string
name: parse_data
arguments: data_tag: D32
datatype: string
name: parse_data
arguments: data_tag: D6
datatype: string

tool: D54: block_write to flash failed - block write not supported by device?

tool: D25: Block-write failed at offset 0x%08x, status=0x%02x


tool: D28: Block locked during block-write process, aborted, status=0x%02x


tool: D42: Command sequence error during block-write, aborted, status=0x%02x


tool: D32: Vpp voltage droop error during block-write, aborted, status=0x%02x


tool: D6: ERROR on block-write - flash is busy even after 0x%x checks


assistant: ```c
void block_write(int addr16b, int *data) {
  int j, f, status;
  unlock_block_for_writes(addr16b);
  flash_write(addr16b, 0xe8);
  if ((flash_read(addr16b) & 0x80) == 0)
    warnx("block_write to flash failed - block write not supported by device?");
  flash_write(addr16b, 0x1f);
  for (j = 0; j < 0x20; j++)
    flash_write(addr16b + j, data[j]);
  flash_write(addr16b, 0xd0);
  status = flash_read(addr16b);
  for (j = 0; ((status & 0x80) == 0) && (j < 0xfff); j++)
    status = flash_read(addr16b);
  if ((status & 0x80) == 0)
    warnx("ERROR on block-write - flash is busy even after 0x%x checks\n", j);
  status = flash_read_status(addr16b);
  if ((status & (1 << 3)) != 0)
    warnx("Vpp voltage droop error during block-write, aborted, status=0x%02x\n", status);
  if ((status & (3 << 4)) != 0)
    warnx("Command sequence error during block-write, aborted, status=0x%02x\n", status);
  if ((status & (1 << 1)) != 0)
    warnx("Block locked during block-write process, aborted, status=0x%02x\n", status);
  if ((status & (1 << 5)) != 0)
    warnx("Block-write failed at offset 0x%08x, status=0x%02x\n", addr16b << 1, status);
  lock_block_to_prevent_writes(addr16b);
  flash_read_mode(addr16b);
}
```