user: 请将这段汇编代码片段转换成等效的C代码：

```asm
<print_string>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  mov    %edi,%ebx
  mov    %rsi,%rbp
  mov    %edx,%r12d
  mov    %ecx,%r15d
  mov    %edi,%r13d
  test   %rsi,%rsi
  je     L190
L36:
  mov    %r12d,%eax
  shr    $0x1f,%eax
  mov    %eax,%r14d
  test   %bl,%bl
  jne    L228
  test   %al,%al
  jne    L37
L228:
  test   %r15b,%r15b
  jne    L189
  test   %r12d,%r12d
  je     L56
L88:
  mov    $0x0,%ebx
L13:
  movzbl 0x0(%rbp),%edi
  mov    %edi,%eax
  or     %r13b,%al
  je     L56
  add    $0x1,%rbp
  test   %dil,%dil
  jne    L111
  mov    $0x2d,%edi
  call   <putchar@plt>
L135:
  add    $0x1,%ebx
  cmp    %ebx,%r12d
  jg     L13
  test   %r14b,%r14b
  jne    L13
  jmp    L56
L190:
  lea    D37(%rip),%rsi
  lea    D28(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%edi
  call   <exit@plt>
  jmp    L36
L37:
  lea    D57(%rip),%rsi
  lea    D28(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%edi
  call   <exit@plt>
  test   %r15b,%r15b
  jne    L126
  jmp    L88
L189:
  test   %r12d,%r12d
  je     L56
L126:
  mov    %rbp,%rbx
  mov    $0x1,%r15d
  sub    %ebp,%r15d
  jmp    L226
L74:
  movzbl %sil,%esi
  lea    D55(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L48
L193:
  add    $0x1,%rbx
  mov    %r13d,%eax
  or     (%rbx),%al
  jne    L45
L226:
  movzbl (%rbx),%esi
  mov    %esi,%eax
  or     %r13b,%al
  je     L56
  test   %sil,%sil
  jne    L74
  lea    D16(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L48:
  lea    (%r15,%rbx,1),%eax
  cmp    %eax,%r12d
  jg     L193
  test   %r14b,%r14b
  jne    L193
L56:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L45:
  mov    $0x3a,%edi
  call   <putchar@plt>
  jmp    L226
L111:
  movzbl %dil,%edi
  call   <putchar@plt>
  jmp    L135
```

tool_calls: name: retrieve_data
arguments: data_label: D37
type: string
name: retrieve_data
arguments: data_label: D28
type: string
name: retrieve_data
arguments: data_label: D57
type: string
name: retrieve_data
arguments: data_label: D55
type: string
name: retrieve_data
arguments: data_label: D16
type: string

tool: D37: Null Pointer Exception - print_string

tool: D28: Error:	%s


tool: D57: Invalid Argument Exception - must end with length or null value

tool: D55: %02X

tool: D16: --

assistant: ```c
void print_string(char ignore_nulls_flag, char *str, int len, char hex_flag) {
  int n = 0;
  unsigned char c = 0;
  if (str == 0) {
    printf("Error:\t%s\n", "Null Pointer Exception - print_string");
    exit(-1);
  }
  if ((len < 0 && !ignore_nulls_flag)) {
    printf("Error:\t%s\n", "Invalid Argument Exception - must end with length or null value");
    exit(-1);
  }
  if (hex_flag) {
    for (n = 0; (n < len || len < 0) && (*str || ignore_nulls_flag); n++) {
      c = (unsigned char)(*str++);
      if (c == 0) {
        printf("--");
      } else {
        printf("%02X", c);
      }
      if ((n + 1 < len || len < 0) && (*str || ignore_nulls_flag))
        printf(":");
    }
  } else {
    for (n = 0; (n < len || len < 0) && (*str || ignore_nulls_flag); n++) {
      c = (unsigned char)(*str++);
      if (c == 0) {
        printf("-");
      } else {
        printf("%c", c);
      }
    }
  }
}
```