user: 下面的汇编指令对应的C源代码是什么：

```asm
<ti_macd>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %edi,0x18(%rsp)
  mov    %rdx,%rbx
  mov    %rcx,0x10(%rsp)
  cvttsd2si (%rdx),%r12d
  cvttsd2si 0x8(%rdx),%ebp
  cvttsd2si 0x10(%rdx),%ecx
  mov    %ecx,0x1c(%rsp)
  cmp    $0x1,%ebp
  setle  %al
  test   %r12d,%r12d
  setle  %dl
  or     %edx,%eax
  cmp    %ebp,%r12d
  setg   %dl
  or     %dl,%al
  jne    L102
  test   %ecx,%ecx
  jg     L121
L102:
  mov    $0x1,%eax
L97:
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L121:
  mov    (%rsi),%r15
  mov    0x10(%rsp),%rax
  mov    (%rax),%r14
  mov    0x8(%rax),%r13
  mov    0x10(%rax),%rax
  mov    %rax,0x8(%rsp)
  mov    %rbx,%rdi
  call   <ti_macd_start@plt>
  mov    %eax,%edx
  mov    $0x0,%eax
  cmp    0x18(%rsp),%edx
  jge    L97
  pxor   %xmm0,%xmm0
  cvtsi2sdl 0x1c(%rsp),%xmm0
  addsd  D43(%rip),%xmm0
  movsd  D42(%rip),%xmm7
  divsd  %xmm0,%xmm7
  cmp    $0xc,%r12d
  jne    L99
  cmp    $0x1a,%ebp
  jne    L99
  movsd  D4(%rip),%xmm5
  movsd  D51(%rip),%xmm6
  jmp    L39
L99:
  pxor   %xmm0,%xmm0
  cvtsi2sd %r12d,%xmm0
  movsd  D43(%rip),%xmm1
  addsd  %xmm1,%xmm0
  movsd  D42(%rip),%xmm5
  movapd %xmm5,%xmm6
  divsd  %xmm0,%xmm6
  pxor   %xmm0,%xmm0
  cvtsi2sd %ebp,%xmm0
  addsd  %xmm1,%xmm0
  divsd  %xmm0,%xmm5
L39:
  movsd  (%r15),%xmm1
  mov    0x18(%rsp),%eax
  cmp    $0x1,%eax
  jle    L20
  lea    -0x2(%rax),%edx
  add    $0x2,%rdx
  movapd %xmm1,%xmm2
  mov    $0x1,%eax
  pxor   %xmm4,%xmm4
  sub    $0x1,%ebp
  jmp    L94
L91:
  movapd %xmm0,%xmm4
L49:
  movapd %xmm0,%xmm3
  subsd  %xmm4,%xmm3
  mulsd  %xmm7,%xmm3
  addsd  %xmm3,%xmm4
  movsd  %xmm0,(%r14)
  movsd  %xmm4,0x0(%r13)
  subsd  %xmm4,%xmm0
  mov    0x8(%rsp),%rsi
  movsd  %xmm0,(%rsi)
  lea    0x8(%rsi),%rdi
  mov    %rdi,0x8(%rsp)
  lea    0x8(%r13),%r13
  lea    0x8(%r14),%r14
L113:
  add    $0x1,%rax
  cmp    %rdx,%rax
  je     L20
L94:
  movsd  (%r15,%rax,8),%xmm0
  movapd %xmm0,%xmm3
  subsd  %xmm1,%xmm3
  mulsd  %xmm6,%xmm3
  addsd  %xmm3,%xmm1
  subsd  %xmm2,%xmm0
  mulsd  %xmm5,%xmm0
  addsd  %xmm0,%xmm2
  movapd %xmm1,%xmm0
  subsd  %xmm2,%xmm0
  cmp    %eax,%ebp
  je     L91
  jg     L113
  jmp    L49
L20:
  mov    0x10(%rsp),%rbp
  sub    0x0(%rbp),%r14
  sar    $0x3,%r14
  mov    %rbx,%rdi
  call   <ti_macd_start@plt>
  mov    %eax,%edx
  mov    0x18(%rsp),%r15d
  mov    %r15d,%eax
  sub    %edx,%eax
  cltq
  cmp    %r14,%rax
  sete   %dil
  movzbl %dil,%edi
  call   <assert@plt>
  mov    %rbp,%r14
  sub    0x8(%rbp),%r13
  sar    $0x3,%r13
  mov    %rbx,%rdi
  call   <ti_macd_start@plt>
  mov    %eax,%edx
  mov    %r15d,%eax
  sub    %edx,%eax
  cltq
  cmp    %r13,%rax
  sete   %dil
  movzbl %dil,%edi
  call   <assert@plt>
  mov    0x8(%rsp),%rbp
  sub    0x10(%r14),%rbp
  sar    $0x3,%rbp
  mov    %rbx,%rdi
  call   <ti_macd_start@plt>
  mov    %eax,%edx
  mov    %r15d,%eax
  sub    %edx,%eax
  cltq
  cmp    %rbp,%rax
  sete   %dil
  movzbl %dil,%edi
  call   <assert@plt>
  mov    $0x0,%eax
  jmp    L97
```

tool_calls: name: disassemble_data
arguments: data_label: D43
type_guessed: f64
name: disassemble_data
arguments: data_label: D42
type_guessed: f64
name: disassemble_data
arguments: data_label: D4
type_guessed: f64
name: disassemble_data
arguments: data_label: D51
type_guessed: f64

tool: D43: 1

tool: D42: 2

tool: D4: 0.075

tool: D51: 0.15

assistant: ```c
int ti_macd(int size, double const *const *inputs, double const *options, double *const *outputs) {
  const double *input = inputs[0];
  double *macd = outputs[0];
  double *signal = outputs[1];
  double *hist = outputs[2];
  const int short_period = (int)options[0];
  const int long_period = (int)options[1];
  const int signal_period = (int)options[2];
  if (short_period < 1)
    return 1;
  if (long_period < 2)
    return 1;
  if (long_period < short_period)
    return 1;
  if (signal_period < 1)
    return 1;
  if (size <= ti_macd_start(options))
    return 0;
  double short_per = 2 / ((double)short_period + 1);
  double long_per = 2 / ((double)long_period + 1);
  double signal_per = 2 / ((double)signal_period + 1);
  if (short_period == 12 && long_period == 26) {
    short_per = 0.15;
    long_per = 0.075;
  }
  double short_ema = input[0];
  double long_ema = input[0];
  double signal_ema = 0;
  int i;
  for (i = 1; i < size; ++i) {
    short_ema = (input[i] - short_ema) * short_per + short_ema;
    long_ema = (input[i] - long_ema) * long_per + long_ema;
    const double out = short_ema - long_ema;
    if (i == long_period - 1) {
      signal_ema = out;
    }
    if (i >= long_period - 1) {
      signal_ema = (out - signal_ema) * signal_per + signal_ema;
      *macd++ = out;
      *signal++ = signal_ema;
      *hist++ = out - signal_ema;
    }
  }
  assert(macd - outputs[0] == size - ti_macd_start(options));
  assert(signal - outputs[1] == size - ti_macd_start(options));
  assert(hist - outputs[2] == size - ti_macd_start(options));
  return 0;
}
```