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

```asm
<print_device>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    -0x38(%rbp),%rax
  mov    %rax,%rsi
  lea    D123(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_action@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L142
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D34(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L142:
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_syspath@plt>
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D68(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_sysname@plt>
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D153(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_sysnum@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L45
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D52(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L45:
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_devpath@plt>
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D31(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_subsystem@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L141
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D65(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L141:
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_devtype@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L38
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D76(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L38:
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_driver@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L82
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D67(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L82:
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_devnode@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L8
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D115(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L8:
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_devnum@plt>
  mov    %eax,-0x24(%rbp)
  mov    -0x24(%rbp),%eax
  mov    %eax,%edi
  call   <major@plt>
  test   %eax,%eax
  jle    L87
  mov    -0x24(%rbp),%eax
  mov    %eax,%edi
  call   <minor@plt>
  mov    %eax,%ebx
  mov    -0x24(%rbp),%eax
  mov    %eax,%edi
  call   <major@plt>
  mov    %ebx,%edx
  mov    %eax,%esi
  lea    D98(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L87:
  movl   $0x0,-0x28(%rbp)
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_devlinks_list_entry@plt>
  mov    %rax,-0x20(%rbp)
  jmp    L49
L62:
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_list_entry_get_name@plt>
  mov    %rax,%rsi
  lea    D187(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  addl   $0x1,-0x28(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_list_entry_get_next@plt>
  mov    %rax,-0x20(%rbp)
L49:
  cmpq   $0x0,-0x20(%rbp)
  jne    L62
  cmpl   $0x0,-0x28(%rbp)
  jle    L40
  mov    -0x28(%rbp),%eax
  mov    %eax,%esi
  lea    D124(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L40:
  movl   $0x0,-0x28(%rbp)
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_device_get_properties_list_entry@plt>
  mov    %rax,-0x20(%rbp)
  jmp    L96
L5:
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_list_entry_get_value@plt>
  mov    %rax,%rbx
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_list_entry_get_name@plt>
  mov    %rbx,%rdx
  mov    %rax,%rsi
  lea    D112(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  addl   $0x1,-0x28(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <udev_list_entry_get_next@plt>
  mov    %rax,-0x20(%rbp)
L96:
  cmpq   $0x0,-0x20(%rbp)
  jne    L5
  cmpl   $0x0,-0x28(%rbp)
  jle    L68
  mov    -0x28(%rbp),%eax
  mov    %eax,%esi
  lea    D71(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L68:
  mov    -0x38(%rbp),%rax
  lea    D46(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <udev_device_get_property_value@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L31
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D157(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L31:
  mov    -0x38(%rbp),%rax
  lea    D77(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <udev_device_get_sysattr_value@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L88
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D50(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L88:
  mov    $0xa,%edi
  call   <putchar@plt>
  nop
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

tool_calls: name: unpack_data
arguments: data_label: D123
type_guessed: string
name: unpack_data
arguments: data_label: D34
type_guessed: string
name: unpack_data
arguments: data_label: D68
type_guessed: string
name: unpack_data
arguments: data_label: D153
type_guessed: string
name: unpack_data
arguments: data_label: D52
type_guessed: string
name: unpack_data
arguments: data_label: D31
type_guessed: string
name: unpack_data
arguments: data_label: D65
type_guessed: string
name: unpack_data
arguments: data_label: D76
type_guessed: string
name: unpack_data
arguments: data_label: D67
type_guessed: string
name: unpack_data
arguments: data_label: D115
type_guessed: string
name: unpack_data
arguments: data_label: D98
type_guessed: string
name: unpack_data
arguments: data_label: D187
type_guessed: string
name: unpack_data
arguments: data_label: D124
type_guessed: string
name: unpack_data
arguments: data_label: D112
type_guessed: string
name: unpack_data
arguments: data_label: D71
type_guessed: string
name: unpack_data
arguments: data_label: D46
type_guessed: string
name: unpack_data
arguments: data_label: D157
type_guessed: string
name: unpack_data
arguments: data_label: D77
type_guessed: string
name: unpack_data
arguments: data_label: D50
type_guessed: string

tool: D123: *** device: %p ***


tool: D34: action:    '%s'


tool: D68: syspath:   '%s'


tool: D153: sysname:   '%s'


tool: D52: sysnum:    '%s'


tool: D31: devpath:   '%s'


tool: D65: subsystem: '%s'


tool: D76: devtype:   '%s'


tool: D67: driver:    '%s'


tool: D115: devname:   '%s'


tool: D98: devnum:    %u:%u


tool: D187: link:      '%s'


tool: D124: found %i links


tool: D112: property:  '%s=%s'


tool: D71: found %i properties


tool: D46: MAJOR

tool: D157: MAJOR: '%s'


tool: D77: dev

tool: D50: attr{dev}: '%s'


assistant: ```c
void print_device(struct udev_device *device) {
  const char *str;
  dev_t devnum;
  int count;
  struct udev_list_entry *list_entry;
  printf("*** device: %p ***\n", device);
  str = udev_device_get_action(device);
  if (str != NULL)
    printf("action:    '%s'\n", str);
  str = udev_device_get_syspath(device);
  printf("syspath:   '%s'\n", str);
  str = udev_device_get_sysname(device);
  printf("sysname:   '%s'\n", str);
  str = udev_device_get_sysnum(device);
  if (str != NULL)
    printf("sysnum:    '%s'\n", str);
  str = udev_device_get_devpath(device);
  printf("devpath:   '%s'\n", str);
  str = udev_device_get_subsystem(device);
  if (str != NULL)
    printf("subsystem: '%s'\n", str);
  str = udev_device_get_devtype(device);
  if (str != NULL)
    printf("devtype:   '%s'\n", str);
  str = udev_device_get_driver(device);
  if (str != NULL)
    printf("driver:    '%s'\n", str);
  str = udev_device_get_devnode(device);
  if (str != NULL)
    printf("devname:   '%s'\n", str);
  devnum = udev_device_get_devnum(device);
  if (major(devnum) > 0)
    printf("devnum:    %u:%u\n", major(devnum), minor(devnum));
  count = 0;
  for (list_entry = udev_device_get_devlinks_list_entry(device); list_entry != NULL; list_entry = udev_list_entry_get_next(list_entry)) {
    printf("link:      '%s'\n", udev_list_entry_get_name(list_entry));
    count++;
  }
  if (count > 0)
    printf("found %i links\n", count);
  count = 0;
  for (list_entry = udev_device_get_properties_list_entry(device); list_entry != NULL; list_entry = udev_list_entry_get_next(list_entry)) {
    printf("property:  '%s=%s'\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
    count++;
  }
  if (count > 0)
    printf("found %i properties\n", count);
  str = udev_device_get_property_value(device, "MAJOR");
  if (str != NULL)
    printf("MAJOR: '%s'\n", str);
  str = udev_device_get_sysattr_value(device, "dev");
  if (str != NULL)
    printf("attr{dev}: '%s'\n", str);
  printf("\n");
}
```