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

```asm
<calc_string>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0xe8,%rsp
  mov    %rdi,%r12
  mov    %fs:0x28,%rax
  mov    %rax,0xd8(%rsp)
  xor    %eax,%eax
  movq   $0x0,(%rsp)
  movq   $0x0,0x8(%rsp)
  movq   $0x0,0x10(%rsp)
  movq   $0x0,0x18(%rsp)
  movq   $0x0,0x20(%rsp)
  movq   $0x0,0x28(%rsp)
  movq   $0x0,0x30(%rsp)
  movq   $0x0,0x38(%rsp)
  movq   $0x0,0x40(%rsp)
  movq   $0x0,0x48(%rsp)
  movq   $0x0,0x50(%rsp)
  movq   $0x0,0x58(%rsp)
  movl   $0x0,0x60(%rsp)
  movq   $0x0,0x70(%rsp)
  movq   $0x0,0x78(%rsp)
  movq   $0x0,0x80(%rsp)
  movq   $0x0,0x88(%rsp)
  movq   $0x0,0x90(%rsp)
  movq   $0x0,0x98(%rsp)
  movq   $0x0,0xa0(%rsp)
  movq   $0x0,0xa8(%rsp)
  movq   $0x0,0xb0(%rsp)
  movq   $0x0,0xb8(%rsp)
  movq   $0x0,0xc0(%rsp)
  movq   $0x0,0xc8(%rsp)
  movl   $0x0,0xd0(%rsp)
  call   <strlen@plt>
  test   %eax,%eax
  jle    L16
  mov    %eax,%ebp
  mov    %r12,%rdx
  mov    $0x0,%ebx
L120:
  mov    %rdx,%r13
  movzbl (%rdx),%eax
  lea    -0x2a(%rax),%ecx
  cmp    $0x1,%cl
  jbe    L156
  and    $0xfffffffd,%eax
  cmp    $0x2d,%al
  je     L156
  add    $0x1,%ebx
  add    $0x1,%rdx
  cmp    %ebx,%ebp
  jne    L120
L16:
  mov    0xd8(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L21
  add    $0xe8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L156:
  mov    %rsp,%rdi
  mov    %ebx,%edx
  mov    %r12,%rsi
  call   <strncpy@plt>
  movzbl 0x0(%r13),%r14d
  lea    0x1(%rbx),%r15d
  cmp    %ebx,%ebp
  jle    L81
  movslq %ebx,%r13
  movslq %r15d,%r15
  jmp    L155
L57:
  add    $0x1,%r13
  cmp    %r13d,%ebp
  jle    L81
L155:
  cmpb   $0x3d,(%r12,%r13,1)
  jne    L57
  mov    %r13d,%edx
  sub    %ebx,%edx
  sub    $0x1,%edx
  lea    (%r12,%r15,1),%rsi
  lea    0x70(%rsp),%rdi
  call   <strncpy@plt>
  jmp    L57
L81:
  cmp    $0x2d,%r14b
  je     L179
  jg     L75
  cmp    $0x2a,%r14b
  je     L128
  cmp    $0x2b,%r14b
  jne    L16
  mov    %rsp,%rdi
  call   <atoi@plt>
  mov    %eax,%ebx
  lea    0x70(%rsp),%rdi
  call   <atoi@plt>
  add    %ebx,%eax
  jmp    L16
L75:
  cmp    $0x2f,%r14b
  jne    L16
  lea    0x70(%rsp),%rdi
  call   <atoi@plt>
  test   %eax,%eax
  je     L16
  mov    %rsp,%rdi
  call   <atoi@plt>
  mov    %eax,%ebx
  lea    0x70(%rsp),%rdi
  call   <atoi@plt>
  mov    %eax,%ecx
  mov    %ebx,%eax
  cltd
  idiv   %ecx
  jmp    L16
L179:
  mov    %rsp,%rdi
  call   <atoi@plt>
  mov    %eax,%ebx
  lea    0x70(%rsp),%rdi
  call   <atoi@plt>
  mov    %eax,%edx
  mov    %ebx,%eax
  sub    %edx,%eax
  jmp    L16
L128:
  mov    %rsp,%rdi
  call   <atoi@plt>
  mov    %eax,%ebx
  lea    0x70(%rsp),%rdi
  call   <atoi@plt>
  imul   %ebx,%eax
  jmp    L16
L21:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int calc_string(const char *s) {
  char buf1[100] = {0};
  char oper1 = 0;
  char buf2[100] = {0};
  int len = strlen(s);
  int i;
  for (i = 0; i < len; i++) {
    if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
      strncpy(buf1, s, i);
      oper1 = s[i];
      break;
    }
  }
  int start = i + 1;
  for (; i < len; i++) {
    if (s[i] == '=') {
      strncpy(buf2, &s[start], i - start);
    }
  }
  switch (oper1) {
  case '+':
    return atoi(buf1) + atoi(buf2);
  case '-':
    return atoi(buf1) - atoi(buf2);
  case '*':
    return atoi(buf1) * atoi(buf2);
  case '/': {
    int a = atoi(buf2);
    if (a)
      return atoi(buf1) / atoi(buf2);
    else
      return 0;
  }
  }
}
```