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

```asm
<coupon_vli>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %esi,-0x1c(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    %rcx,-0x30(%rbp)
  mov    %r8d,-0x20(%rbp)
  mov    %r9d,-0x34(%rbp)
  mov    -0x28(%rbp),%rax
  sub    -0x18(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x1c(%rbp),%eax
  cltq
  cmp    %rax,%rdx
  jl     L103
  mov    0x20(%rbp),%rax
  movl   $0x3,(%rax)
  mov    -0x28(%rbp),%rax
  sub    -0x18(%rbp),%rax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x30(%rbp),%rdx
  mov    0x30(%rbp),%rax
  lea    D11(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  mov    $0x0,%eax
  jmp    L53
L103:
  mov    -0x28(%rbp),%rax
  mov    $0x1,%esi
  mov    %rax,%rdi
  call   <to_int@plt>
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  cmp    -0x34(%rbp),%eax
  jl     L86
  mov    -0xc(%rbp),%eax
  cmp    0x10(%rbp),%eax
  jle    L75
L86:
  cmpl   $0x9,-0xc(%rbp)
  jne    L123
  cmpl   $0x0,0x18(%rbp)
  jne    L75
L123:
  mov    0x20(%rbp),%rax
  movl   $0x3,(%rax)
  mov    -0x28(%rbp),%rax
  sub    -0x18(%rbp),%rax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%ecx
  cmpl   $0x0,-0xc(%rbp)
  jns    L56
  lea    D16(%rip),%rax
  jmp    L23
L56:
  lea    D5(%rip),%rax
L23:
  mov    -0x30(%rbp),%rdx
  mov    0x30(%rbp),%rdi
  mov    %rax,%rsi
  mov    $0x0,%eax
  call   <sprintf@plt>
  mov    $0x0,%eax
  jmp    L53
L75:
  addq   $0x1,-0x28(%rbp)
  cmpl   $0x9,-0xc(%rbp)
  jne    L88
  cmpl   $0x0,0x18(%rbp)
  jne    L137
L88:
  mov    -0x28(%rbp),%rax
  sub    -0x18(%rbp),%rax
  mov    %rax,%rdx
  mov    -0xc(%rbp),%eax
  cltq
  add    %rax,%rdx
  mov    -0x20(%rbp),%eax
  cltq
  add    %rax,%rdx
  mov    -0x1c(%rbp),%eax
  cltq
  cmp    %rax,%rdx
  jle    L78
  mov    0x20(%rbp),%rax
  movl   $0x3,(%rax)
  mov    -0x28(%rbp),%rax
  sub    -0x18(%rbp),%rax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x30(%rbp),%rdx
  mov    0x30(%rbp),%rax
  lea    D2(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  mov    $0x0,%eax
  jmp    L53
L78:
  mov    -0xc(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x20(%rbp),%eax
  cltq
  add    %rax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  jmp    L120
L62:
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jbe    L178
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x39,%al
  jbe    L136
L178:
  mov    0x20(%rbp),%rax
  movl   $0x3,(%rax)
  mov    -0x28(%rbp),%rax
  sub    -0x18(%rbp),%rax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%ecx
  mov    -0x30(%rbp),%rdx
  mov    0x30(%rbp),%rax
  lea    D49(%rip),%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sprintf@plt>
  mov    $0x0,%eax
  jmp    L53
L136:
  addq   $0x1,-0x28(%rbp)
L120:
  mov    -0x28(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jb     L62
L137:
  mov    -0x28(%rbp),%rax
L53:
  leave
  ret
```

tool_calls: name: parse_data
arguments: data_label: D11
type_infered: string
name: parse_data
arguments: data_label: D16
type_infered: string
name: parse_data
arguments: data_label: D5
type_infered: string
name: parse_data
arguments: data_label: D2
type_infered: string
name: parse_data
arguments: data_label: D49
type_infered: string

tool: D11: %s VLI missing

tool: D16: Non-numeric %s VLI '%c'

tool: D5: Invalid %s VLI '%c'

tool: D2: %s incomplete

tool: D49: Non-numeric %s '%c'

assistant: ```c
const unsigned char *coupon_vli(const unsigned char *data, const int data_len, const unsigned char *d, const char *name, const int vli_offset, const int vli_min, const int vli_max, const int vli_nine, int *p_err_no, int *p_err_posn, char err_msg[50]) {
  const unsigned char *de;
  int vli;
  if (d - data + 1 > data_len) {
    *p_err_no = 3;
    *p_err_posn = d - data + 1;
    sprintf(err_msg, "%s VLI missing", name);
    return NULL;
  }
  vli = to_int(d, 1);
  if ((vli < vli_min || vli > vli_max) && (vli != 9 || !vli_nine)) {
    *p_err_no = 3;
    *p_err_posn = d - data + 1;
    sprintf(err_msg, vli < 0 ? "Non-numeric %s VLI '%c'" : "Invalid %s VLI '%c'", name, *d);
    return NULL;
  }
  d++;
  if (vli != 9 || !vli_nine) {
    if (d - data + vli + vli_offset > data_len) {
      *p_err_no = 3;
      *p_err_posn = d - data + 1;
      sprintf(err_msg, "%s incomplete", name);
      return NULL;
    }
    de = d + vli + vli_offset;
    for (; d < de; d++) {
      if (*d < '0' || *d > '9') {
        *p_err_no = 3;
        *p_err_posn = d - data + 1;
        sprintf(err_msg, "Non-numeric %s '%c'", name, *d);
        return NULL;
      }
    }
  }
  return d;
}
```