user: 请从给定的汇编指令推导出C源代码：

```asm
<bcd2_add>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  lea    -0x20(%rbp),%rdx
  lea    -0x28(%rbp),%rcx
  mov    -0x48(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <bin_bcd2@plt>
  movq   $0x0,-0x18(%rbp)
  movl   $0x0,-0x2c(%rbp)
  jmp    L10
L84:
  cmpl   $0x6,-0x2c(%rbp)
  jle    L40
  mov    -0x40(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x2c(%rbp),%eax
  sub    $0x7,%eax
  shl    $0x2,%eax
  mov    $0xf,%esi
  mov    %eax,%ecx
  shl    %cl,%esi
  mov    %esi,%eax
  cltq
  and    %rax,%rdx
  mov    -0x2c(%rbp),%eax
  sub    $0x7,%eax
  shl    $0x2,%eax
  mov    %eax,%ecx
  sar    %cl,%rdx
  mov    %rdx,%rax
  jmp    L70
L40:
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x2c(%rbp),%eax
  shl    $0x2,%eax
  mov    $0xf,%esi
  mov    %eax,%ecx
  shl    %cl,%esi
  mov    %esi,%eax
  cltq
  and    %rax,%rdx
  mov    -0x2c(%rbp),%eax
  shl    $0x2,%eax
  mov    %eax,%ecx
  sar    %cl,%rdx
  mov    %rdx,%rax
L70:
  mov    %rax,-0x10(%rbp)
  cmpl   $0x6,-0x2c(%rbp)
  jle    L47
  mov    -0x2c(%rbp),%eax
  sub    $0x7,%eax
  shl    $0x2,%eax
  mov    $0xf,%edx
  mov    %eax,%ecx
  shl    %cl,%edx
  mov    %edx,%eax
  movslq %eax,%rdx
  mov    -0x20(%rbp),%rax
  and    %rax,%rdx
  mov    -0x2c(%rbp),%eax
  sub    $0x7,%eax
  shl    $0x2,%eax
  mov    %eax,%ecx
  sar    %cl,%rdx
  mov    %rdx,%rax
  jmp    L44
L47:
  mov    -0x2c(%rbp),%eax
  shl    $0x2,%eax
  mov    $0xf,%edx
  mov    %eax,%ecx
  shl    %cl,%edx
  mov    %edx,%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  and    %rax,%rdx
  mov    -0x2c(%rbp),%eax
  shl    $0x2,%eax
  mov    %eax,%ecx
  sar    %cl,%rdx
  mov    %rdx,%rax
L44:
  add    %rax,-0x10(%rbp)
  mov    -0x18(%rbp),%rax
  add    %rax,-0x10(%rbp)
  mov    -0x10(%rbp),%rcx
  movabs $0x6666666666666667,%rdx
  mov    %rcx,%rax
  imul   %rdx
  mov    %rdx,%rax
  sar    $0x2,%rax
  sar    $0x3f,%rcx
  mov    %rcx,%rdx
  sub    %rdx,%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x10(%rbp),%rcx
  movabs $0x6666666666666667,%rdx
  mov    %rcx,%rax
  imul   %rdx
  mov    %rdx,%rax
  sar    $0x2,%rax
  mov    %rcx,%rsi
  sar    $0x3f,%rsi
  sub    %rsi,%rax
  mov    %rax,%rdx
  mov    %rdx,%rax
  shl    $0x2,%rax
  add    %rdx,%rax
  add    %rax,%rax
  sub    %rax,%rcx
  mov    %rcx,%rdx
  mov    %rdx,-0x10(%rbp)
  cmpl   $0x6,-0x2c(%rbp)
  jle    L50
  mov    -0x40(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x2c(%rbp),%eax
  sub    $0x7,%eax
  shl    $0x2,%eax
  mov    $0xf,%esi
  mov    %eax,%ecx
  shl    %cl,%esi
  mov    %esi,%eax
  xor    $0xfffffff,%eax
  cltq
  and    %rax,%rdx
  mov    -0x40(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x40(%rbp),%rax
  mov    (%rax),%rsi
  mov    -0x2c(%rbp),%eax
  sub    $0x7,%eax
  shl    $0x2,%eax
  mov    -0x10(%rbp),%rdx
  mov    %eax,%ecx
  shl    %cl,%rdx
  mov    %rdx,%rax
  or     %rax,%rsi
  mov    %rsi,%rdx
  mov    -0x40(%rbp),%rax
  mov    %rdx,(%rax)
  jmp    L75
L50:
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x2c(%rbp),%eax
  shl    $0x2,%eax
  mov    $0xf,%esi
  mov    %eax,%ecx
  shl    %cl,%esi
  mov    %esi,%eax
  xor    $0xfffffff,%eax
  cltq
  and    %rax,%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rsi
  mov    -0x2c(%rbp),%eax
  shl    $0x2,%eax
  mov    -0x10(%rbp),%rdx
  mov    %eax,%ecx
  shl    %cl,%rdx
  mov    %rdx,%rax
  or     %rax,%rsi
  mov    %rsi,%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,(%rax)
L75:
  addl   $0x1,-0x2c(%rbp)
L10:
  cmpl   $0xd,-0x2c(%rbp)
  jle    L84
  mov    -0x18(%rbp),%rax
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L67
  call   <__stack_chk_fail@plt>
L67:
  leave
  ret
```

assistant: ```c
int bcd2_add(long *bcd_low, long *bcd_high, long addend) {
  long tmp_lo, tmp_hi, carry, res;
  int digit;
  bin_bcd2(addend, &tmp_lo, &tmp_hi);
  carry = 0;
  for (digit = 0; digit < 14; digit++) {
    res = ((digit) >= 7) ? (*bcd_high & (0xF << (4 * ((digit)-7)))) >> (((digit)-7) * 4) : (*bcd_low & (0xF << (4 * (digit)))) >> ((digit)*4);
    res += ((digit) >= 7) ? (tmp_hi & (0xF << (4 * ((digit)-7)))) >> (((digit)-7) * 4) : (tmp_lo & (0xF << (4 * (digit)))) >> ((digit)*4);
    res += carry;
    carry = res / 10;
    res %= 10;
    if ((digit) >= 7) {
      *bcd_high &= (0xFFFFFFF ^ (0xF << (4 * ((digit)-7))));
      *bcd_high |= (res << (4 * ((digit)-7)));
    } else {
      *bcd_low = (*bcd_low & (0xFFFFFFF ^ (0xF << (4 * (digit)))));
      *bcd_low |= (res << (4 * (digit)));
    };
  }
  return (carry);
}
```