user: Translate the below assembly code into C programming language:

```asm
<is_last_char_valid>:
  endbr64
  sub    $0x88,%rsp
  mov    %rdi,%rcx
  movdqa D70(%rip),%xmm7
  movdqa D69(%rip),%xmm6
  mov    %fs:0x28,%rax
  mov    %rax,0x78(%rsp)
  xor    %eax,%eax
  movdqa D33(%rip),%xmm5
  movslq %esi,%rdi
  movdqa D8(%rip),%xmm3
  lea    -0x1(%rdi),%edx
  movl   $0x2,0x70(%rsp)
  movaps %xmm7,0x30(%rsp)
  movaps %xmm6,0x40(%rsp)
  movaps %xmm5,0x50(%rsp)
  movaps %xmm3,0x60(%rsp)
  test   %edx,%edx
  jle    L121
  lea    -0x2(%rdi),%eax
  cmp    $0xe,%eax
  jbe    L85
  movdqu (%rcx),%xmm2
  pxor   %xmm4,%xmm4
  movdqa D24(%rip),%xmm0
  mov    %edx,%esi
  and    $0xfffffff0,%esi
  pcmpgtb %xmm2,%xmm4
  movdqa %xmm2,%xmm1
  punpcklbw %xmm4,%xmm1
  punpckhbw %xmm4,%xmm2
  pxor   %xmm4,%xmm4
  paddw  %xmm0,%xmm1
  movdqa %xmm4,%xmm8
  paddw  %xmm2,%xmm0
  pcmpgtw %xmm1,%xmm8
  pcmpgtw %xmm0,%xmm4
  movdqa %xmm1,%xmm2
  punpcklwd %xmm8,%xmm2
  punpckhwd %xmm8,%xmm1
  movdqa %xmm2,%xmm9
  psrlq  $0x20,%xmm2
  pmuludq %xmm7,%xmm9
  psrlq  $0x20,%xmm7
  pmuludq %xmm7,%xmm2
  pshufd $0x8,%xmm9,%xmm7
  pshufd $0x8,%xmm2,%xmm2
  punpckldq %xmm2,%xmm7
  movdqa %xmm1,%xmm2
  pmuludq %xmm6,%xmm2
  psrlq  $0x20,%xmm1
  psrlq  $0x20,%xmm6
  pmuludq %xmm6,%xmm1
  movdqa %xmm7,%xmm6
  pshufd $0x8,%xmm2,%xmm2
  pshufd $0x8,%xmm1,%xmm1
  punpckldq %xmm1,%xmm2
  movdqa %xmm0,%xmm1
  punpckhwd %xmm4,%xmm0
  punpcklwd %xmm4,%xmm1
  paddd  %xmm2,%xmm6
  movdqa %xmm1,%xmm2
  psrlq  $0x20,%xmm1
  pmuludq %xmm5,%xmm2
  psrlq  $0x20,%xmm5
  pmuludq %xmm5,%xmm1
  pshufd $0x8,%xmm2,%xmm2
  pshufd $0x8,%xmm1,%xmm1
  punpckldq %xmm1,%xmm2
  movdqa %xmm0,%xmm1
  psrlq  $0x20,%xmm1
  pmuludq %xmm3,%xmm0
  paddd  %xmm6,%xmm2
  psrlq  $0x20,%xmm3
  pmuludq %xmm3,%xmm1
  pshufd $0x8,%xmm0,%xmm0
  pshufd $0x8,%xmm1,%xmm1
  punpckldq %xmm1,%xmm0
  paddd  %xmm2,%xmm0
  movdqa %xmm0,%xmm1
  psrldq $0x8,%xmm1
  paddd  %xmm1,%xmm0
  movdqa %xmm0,%xmm1
  psrldq $0x4,%xmm1
  paddd  %xmm1,%xmm0
  movd   %xmm0,%eax
  test   $0xf,%dl
  je     L35
L44:
  movslq %esi,%r9
  movsbl (%rcx,%r9,1),%r8d
  sub    $0x30,%r8d
  imul   0x30(%rsp,%r9,4),%r8d
  add    %r8d,%eax
  lea    0x1(%rsi),%r8d
  cmp    %edx,%r8d
  jge    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0x2(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0x3(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0x4(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0x5(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0x6(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0x7(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0x8(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0x9(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0xa(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0xb(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0xc(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  lea    0xd(%rsi),%r8d
  add    %r9d,%eax
  cmp    %r8d,%edx
  jle    L35
  movslq %r8d,%r8
  add    $0xe,%esi
  movsbl (%rcx,%r8,1),%r9d
  sub    $0x30,%r9d
  imul   0x30(%rsp,%r8,4),%r9d
  add    %r9d,%eax
  cmp    %esi,%edx
  jle    L35
  movslq %esi,%rsi
  movsbl (%rcx,%rsi,1),%edx
  sub    $0x30,%edx
  imul   0x30(%rsp,%rsi,4),%edx
  add    %edx,%eax
  nopw   0x0(%rax,%rax,1)
L35:
  movslq %eax,%rdx
  mov    %eax,%esi
  imul   $0x2e8ba2e9,%rdx,%rdx
  sar    $0x1f,%esi
  sar    $0x21,%rdx
  sub    %esi,%edx
  lea    (%rdx,%rdx,4),%esi
  lea    (%rdx,%rsi,2),%esi
  sub    %esi,%eax
  movslq %eax,%rdx
L156:
  movdqa D74(%rip),%xmm0
  mov    D13(%rip),%rax
  movl   $0x32,0x28(%rsp)
  movaps %xmm0,(%rsp)
  movdqa D48(%rip),%xmm0
  mov    %rax,0x20(%rsp)
  movaps %xmm0,0x10(%rsp)
  movzbl (%rsp,%rdx,4),%eax
  cmp    %al,-0x1(%rcx,%rdi,1)
  sete   %al
  movzbl %al,%eax
  mov    0x78(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L127
  add    $0x88,%rsp
  ret
  nopl   0x0(%rax,%rax,1)
L121:
  xor    %edx,%edx
  jmp    L156
L85:
  xor    %esi,%esi
  xor    %eax,%eax
  jmp    L44
L127:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: unpack_data
arguments: data_label: D70
datatype: byte[16]
name: unpack_data
arguments: data_label: D69
datatype: byte[16]
name: unpack_data
arguments: data_label: D33
datatype: byte[16]
name: unpack_data
arguments: data_label: D8
datatype: byte[16]
name: unpack_data
arguments: data_label: D24
datatype: byte[16]
name: unpack_data
arguments: data_label: D74
datatype: byte[16]
name: unpack_data
arguments: data_label: D13
datatype: byte[8]
name: unpack_data
arguments: data_label: D48
datatype: byte[16]

tool: {"D70": [0x07,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x05,0x00,0x00,0x00]}

tool: {"D69": [0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00]}

tool: {"D33": [0x06,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x09,0x00,0x00,0x00]}

tool: {"D8": [0x0a,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00]}

tool: {"D24": [0xd0,0xff,0xd0,0xff,0xd0,0xff,0xd0,0xff,0xd0,0xff,0xd0,0xff,0xd0,0xff,0xd0,0xff]}

tool: {"D74": [0x31,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x39,0x00,0x00,0x00]}

tool: {"D13": [0x34,0x00,0x00,0x00,0x33,0x00,0x00,0x00]}

tool: {"D48": [0x38,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x35,0x00,0x00,0x00]}

assistant: ```c
int is_last_char_valid(char id[], int len) {
  int weights[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
  int sum = 0;
  for (int i = 0; i < len - 1; i++) {
    int num = id[i] - '0';
    sum += num * weights[i];
  }
  int z = sum % 11;
  int z_check[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
  char last = z_check[z];
  if (last == id[len - 1]) {
    return 1;
  } else {
    return 0;
  }
}
```