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

```asm
<trie_insert>:
  endbr64
  push   %r15
  push   %r14
  mov    %rsi,%r14
  push   %r13
  push   %r12
  push   %rbp
  mov    %rdi,%rbp
  mov    %rsi,%rdi
  push   %rbx
  sub    $0x18,%rsp
  mov    %rdx,0x8(%rsp)
  call   <strlen@plt>
  mov    %rbp,%rdi
  mov    %ax,0x6(%rsp)
  call   <trie_root@plt>
  mov    %rax,%r15
  test   %rax,%rax
  je     L110
L97:
  xor    %r12d,%r12d
  xor    %r13d,%r13d
  nopl   0x0(%rax)
L30:
  mov    %r15,%rdi
  lea    (%r14,%r13,1),%rbp
  call   <trienode_key@plt>
  movsbl 0x0(%rbp),%edi
  mov    %rax,%rbx
  call   <tolower@plt>
  cmp    %rax,%rbx
  jne    L55
  add    $0x1,%r12d
  mov    %r15,%rdi
  cmp    %r12w,0x6(%rsp)
  jbe    L51
  call   <trienode_next@plt>
  movzwl %r12w,%r13d
  test   %rax,%rax
  je     L0
L24:
  mov    %r15,%rdi
  call   <trienode_next@plt>
  mov    %rax,%r15
  jmp    L30
  nop
L55:
  mov    %r15,%rdi
  call   <trienode_sibling@plt>
  test   %rax,%rax
  je     L44
L115:
  mov    %r15,%rdi
  call   <trienode_sibling@plt>
  mov    %rax,%r15
  jmp    L30
  nopw   0x0(%rax,%rax,1)
L44:
  movsbl 0x0(%rbp),%edi
  call   <trienode_alloc@plt>
  mov    %r15,%rdi
  mov    %rax,%rsi
  call   <trienode_set_sibling@plt>
  jmp    L115
  cs nopw 0x0(%rax,%rax,1)
L0:
  movsbl (%r14,%r13,1),%edi
  call   <trienode_alloc@plt>
  mov    %r15,%rdi
  mov    %rax,%rsi
  call   <trienode_set_next@plt>
  jmp    L24
  nopw   0x0(%rax,%rax,1)
L51:
  call   <trienode_values@plt>
  test   %eax,%eax
  je     L38
L10:
  mov    0x8(%rsp),%rdi
  call   <strdup@plt>
  mov    %eax,%edi
  call   <listnode_alloc@plt>
  mov    %r15,%rdi
  mov    %rax,%rbp
  call   <trienode_values@plt>
  add    $0x18,%rsp
  mov    %rbp,%rsi
  pop    %rbx
  mov    %eax,%edi
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1220 <list_append@plt>
  nopl   (%rax)
L38:
  mov    D5(%rip),%rax
  mov    (%rax),%edi
  call   <list_alloc@plt>
  mov    %r15,%rdi
  mov    %eax,%esi
  call   <trienode_set_values@plt>
  jmp    L10
L110:
  movsbl (%r14),%edi
  call   <tolower@plt>
  movsbl %al,%edi
  call   <trienode_alloc@plt>
  mov    %rbp,%rdi
  mov    %rax,%rsi
  mov    %rax,%r15
  call   <trie_set_root@plt>
  jmp    L97
```

assistant: ```c
void trie_insert(struct Trie *trie, char *keys, char *value) {
  unsigned short key_idx = 0;
  unsigned short key_len = strlen(keys);
  struct TrieNode *node = trie_root(trie);
  if (!node) {
    node = trienode_alloc(tolower(keys[0]));
    trie_set_root(trie, node);
  }
  for (;;) {
    if (trienode_key(node) == tolower(keys[key_idx])) {
      key_idx++;
      if (key_idx >= key_len)
        break;
      else {
        if (!trienode_next(node))
          trienode_set_next(node, trienode_alloc(keys[key_idx]));
        node = trienode_next(node);
      }
    } else {
      if (!trienode_sibling(node))
        trienode_set_sibling(node, trienode_alloc(keys[key_idx]));
      node = trienode_sibling(node);
    }
  }
  if (!trienode_values(node))
    trienode_set_values(node, list_alloc(free));
  struct ListNode *new_value = listnode_alloc(strdup(value));
  list_append(trienode_values(node), new_value);
  return;
}
```