user: Demonstrate the C code that generates the assembly output below:

```asm
<ax25_frame>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  mov    %rsi,%rbp
  push   %rbx
  mov    %rdi,%rbx
  xor    %edi,%edi
  sub    $0x28,%rsp
  mov    0x70(%rsp),%r12
  mov    %rdx,0x18(%rsp)
  mov    0x60(%rsp),%r15d
  mov    0x68(%rsp),%r13d
  mov    %ecx,0x8(%rsp)
  mov    %r12,%rsi
  mov    %r8,0x10(%rsp)
  mov    %r9d,0xc(%rsp)
  call   <va_start@plt>
  movsbl 0xc(%rsp),%edx
  mov    0x10(%rsp),%rsi
  mov    %rbx,%rdi
  call   <_ax25_callsign@plt>
  movsbl 0x8(%rsp),%edx
  mov    0x18(%rsp),%rsi
  mov    %rax,%rdi
  call   <_ax25_callsign@plt>
  test   %r15b,%r15b
  jne    L53
  test   %r13b,%r13b
  jne    L51
L45:
  lea    0x8(%rax),%r8
  orl    $0x1,-0x4(%rax)
  xor    %r14d,%r14d
  mov    %r12,%rdx
  movabs $0xf000000003,%rdi
  mov    %r8,%rsi
  mov    %r14d,%ecx
  sub    %rbx,%rsi
  mov    %rdi,(%rax)
  mov    %r8,%rdi
  sar    $0x2,%rsi
  neg    %rsi
  add    $0xc6,%esi
  call   <vsnprintf@plt>
  mov    %r14d,%edi
  call   <va_end@plt>
  mov    (%rbx),%eax
  mov    %rbx,%rsi
  test   %eax,%eax
  je     L12
  mov    $0xffff,%edx
  nopl   (%rax)
L44:
  xor    %edx,%eax
  mov    %eax,%ecx
  shr    %ecx
  mov    %ecx,%edx
  xor    $0x8408,%edx
  test   $0x1,%al
  cmovne %edx,%ecx
  mov    %ecx,%edx
  shr    %edx
  mov    %edx,%eax
  xor    $0x8408,%eax
  and    $0x1,%ecx
  cmovne %eax,%edx
  mov    %edx,%eax
  shr    %eax
  mov    %eax,%ecx
  xor    $0x8408,%ecx
  and    $0x1,%edx
  cmovne %ecx,%eax
  mov    %eax,%edx
  shr    %edx
  mov    %edx,%ecx
  xor    $0x8408,%ecx
  test   $0x1,%al
  cmovne %ecx,%edx
  mov    %edx,%eax
  shr    %eax
  mov    %eax,%ecx
  xor    $0x8408,%ecx
  and    $0x1,%edx
  cmovne %ecx,%eax
  mov    %eax,%edx
  shr    %edx
  mov    %edx,%ecx
  xor    $0x8408,%ecx
  test   $0x1,%al
  cmovne %ecx,%edx
  mov    %edx,%eax
  shr    %eax
  mov    %eax,%ecx
  xor    $0x8408,%ecx
  and    $0x1,%edx
  cmovne %ecx,%eax
  mov    %eax,%edx
  shr    %edx
  mov    %edx,%ecx
  xor    $0x8408,%ecx
  test   $0x1,%al
  cmovne %ecx,%edx
  mov    0x4(%rsi),%eax
  add    $0x4,%rsi
  test   %eax,%eax
  jne    L44
  movzbl %dl,%eax
  movzbl %dh,%edx
  not    %eax
  not    %edx
L55:
  mov    %eax,(%rsi)
  add    $0x8,%rsi
  mov    %edx,-0x4(%rsi)
  sub    %rbx,%rsi
  sar    $0x2,%rsi
  mov    %esi,0x0(%rbp)
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L53:
  movsbl %r15b,%edx
  lea    D0(%rip),%rsi
  mov    %rax,%rdi
  call   <_ax25_callsign@plt>
  test   %r13b,%r13b
  je     L45
L51:
  movsbl %r13b,%edx
  lea    D1(%rip),%rsi
  mov    %rax,%rdi
  call   <_ax25_callsign@plt>
  jmp    L45
L12:
  mov    $0xffffff00,%edx
  mov    $0xffffff00,%eax
  jmp    L55
```

tool_calls: name: read_data
arguments: label: D0
datatype: string
name: read_data
arguments: label: D1
datatype: string

tool: D0: WIDE1

tool: D1: WIDE2

assistant: ```c
void ax25_frame(uint8_t *frame, int *length, char *scallsign, char sssid, char *dcallsign, char dssid, char ttl1, char ttl2, char *data, ...) {
  uint8_t *s, j;
  uint16_t CRC;
  va_list va;
  va_start(va, data);
  s = _ax25_callsign(frame, dcallsign, dssid);
  s = _ax25_callsign(s, scallsign, sssid);
  if (ttl1)
    s = _ax25_callsign(s, "WIDE1", ttl1);
  if (ttl2)
    s = _ax25_callsign(s, "WIDE2", ttl2);
  s[-1] |= 1;
  *(s++) = 0x03;
  *(s++) = 0xF0;
  vsnprintf((char *)s, 200 - (s - frame) - 2, data, va);
  va_end(va);
  for (CRC = 0xffff, s = frame; *s; s++) {
    CRC ^= ((unsigned int)*s);
    for (j = 0; j < 8; j++) {
      if (CRC & 1) {
        CRC = (CRC >> 1) ^ 0x8408;
      } else {
        CRC >>= 1;
      }
    }
  }
  *(s++) = ~(CRC & 0xFF);
  *(s++) = ~((CRC >> 8) & 0xFF);
  *length = s - frame;
}
```