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

```asm
<gradient>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    (%rsi),%esi
  mov    %esi,-0x1c(%rsp)
  test   %esi,%esi
  jle    L157
  mov    %rdx,%rax
  mov    %rcx,%rdx
  movslq (%rdi),%rcx
  lea    0x0(,%rcx,8),%rsi
  mov    %rcx,%r14
  shl    $0x4,%rcx
  lea    -0x8(%rsi),%r15
  lea    -0x10(%rsi),%rbx
  mov    %rbx,-0x18(%rsp)
  lea    (%r8,%r15,1),%rdi
  lea    (%rax,%rsi,1),%rbp
  cmp    $0x1,%r14d
  jne    L22
  movslq -0x1c(%rsp),%r10
  xor    %r9d,%r9d
  mov    $0x0,%ebx
  mov    %r8,%r13
  mov    %r9,%r12
  mov    $0x0,%r11d
  mov    %r10,%r14
  sub    $0x1,%r10
  imul   %rsi,%r10
  test   %rsi,%rsi
  cmovns %rsi,%r11
  cmovle %rsi,%rbx
  cmovs  %r10,%r12
  cmovs  %r9,%r10
  lea    -0x1(%r14),%r9d
  lea    -0x10(%rax,%rcx,1),%r14
  cmp    $0x2,%r9d
  seta   %r9b
  sub    %rbp,%r13
  cmp    $0x8,%r13
  seta   %r13b
  and    %r13d,%r9d
  mov    %rdi,%r13
  sub    %rbp,%r13
  cmp    $0x8,%r13
  seta   %r13b
  and    %r13d,%r9d
  mov    %rdi,%r13
  sub    %r14,%r13
  lea    (%r8,%r12,1),%r14
  cmp    $0x8,%r13
  seta   %r13b
  and    %r13d,%r9d
  lea    (%r8,%r10,1),%r13
  cmp    %r13,%rdx
  seta   %r13b
  cmp    %r14,%rdx
  setb   %r14b
  or     %r14d,%r13d
  lea    (%r8,%r11,1),%r14
  and    %r13d,%r9d
  mov    -0x18(%rsp),%r13
  add    %rbx,%r13
  add    %rax,%r13
  cmp    %r13,%r14
  setb   %r13b
  add    %r15,%r11
  add    %r8,%rbx
  add    %rax,%r11
  cmp    %rbx,%r11
  setb   %r11b
  or     %r11d,%r13d
  test   %r13b,%r9b
  je     L80
  lea    (%r15,%r12,1),%r9
  add    %r8,%r9
  cmp    %r9,%rdx
  lea    (%r15,%r10,1),%r9
  setb   %r11b
  add    %r8,%r9
  cmp    %r9,%rdx
  seta   %r9b
  or     %r9b,%r11b
  je     L80
  mov    -0x1c(%rsp),%ebp
  movsd  (%rdx),%xmm2
  mov    %rsi,%r10
  xor    %r9d,%r9d
  mov    -0x18(%rsp),%r11
  xor    %ebx,%ebx
  shr    %ebp
  unpcklpd %xmm2,%xmm2
  add    %rax,%r11
  nopl   0x0(%rax)
L38:
  movsd  0x8(%rax,%r9,1),%xmm0
  movsd  (%rax,%r9,1),%xmm1
  add    $0x1,%ebx
  movhpd (%rax,%r10,1),%xmm1
  movhpd 0x8(%rax,%r10,1),%xmm0
  subpd  %xmm1,%xmm0
  divpd  %xmm2,%xmm0
  movlpd %xmm0,(%r8,%r9,1)
  movhpd %xmm0,(%r8,%r10,1)
  movsd  0x8(%r11,%r9,1),%xmm0
  movsd  (%r11,%r9,1),%xmm1
  movhpd 0x8(%r11,%r10,1),%xmm0
  movhpd (%r11,%r10,1),%xmm1
  subpd  %xmm1,%xmm0
  divpd  %xmm2,%xmm0
  movlpd %xmm0,(%rdi,%r9,1)
  add    %rcx,%r9
  movhpd %xmm0,(%rdi,%r10,1)
  add    %rcx,%r10
  cmp    %ebx,%ebp
  jne    L38
  mov    -0x1c(%rsp),%ebx
  mov    %ebx,%edi
  and    $0xfffffffe,%edi
  mov    %edi,%ecx
  imul   %rsi,%rcx
  add    %rcx,%r8
  add    %rcx,%rax
  cmp    %edi,%ebx
  je     L157
  movsd  0x8(%rax),%xmm0
  subsd  (%rax),%xmm0
  divsd  (%rdx),%xmm0
  movsd  %xmm0,(%r8)
  movsd  -0x8(%rax,%rsi,1),%xmm0
  subsd  -0x10(%rax,%rsi,1),%xmm0
  divsd  (%rdx),%xmm0
  movsd  %xmm0,-0x8(%r8,%rsi,1)
L157:
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L22:
  movslq -0x1c(%rsp),%r9
  xor    %r10d,%r10d
  mov    $0x0,%r12d
  mov    %r8,%rbx
  mov    %r10,%r13
  mov    %r9,%r11
  sub    $0x1,%r9
  imul   %rsi,%r9
  test   %rsi,%rsi
  cmovle %rsi,%r12
  cmovns %r9,%r10
  cmovs  %r9,%r13
  mov    $0x0,%r9d
  cmovns %rsi,%r9
  mov    %r10,-0x10(%rsp)
  lea    -0x1(%r11),%r10d
  cmp    $0x2,%r10d
  seta   %r10b
  sub    %rbp,%rbx
  cmp    $0x8,%rbx
  mov    %rdi,%rbx
  seta   %r11b
  sub    %rbp,%rbx
  and    %r11d,%r10d
  cmp    $0x8,%rbx
  lea    -0x10(%rax,%rcx,1),%rbx
  seta   %r11b
  and    %r11d,%r10d
  mov    %rdi,%r11
  sub    %rbx,%r11
  mov    -0x10(%rsp),%rbx
  cmp    $0x8,%r11
  seta   %r11b
  and    %r11d,%r10d
  lea    (%r8,%rbx,1),%r11
  lea    (%r8,%r13,1),%rbx
  cmp    %r11,%rdx
  seta   %r11b
  cmp    %rbx,%rdx
  setb   %bl
  or     %ebx,%r11d
  and    %r11d,%r10d
  lea    (%r8,%r9,1),%r11
  mov    %r10d,%ebx
  mov    -0x18(%rsp),%r10
  add    %r12,%r10
  add    %rax,%r10
  cmp    %r10,%r11
  setb   %r10b
  add    %r15,%r9
  add    %r8,%r12
  add    %rax,%r9
  cmp    %r12,%r9
  setb   %r9b
  or     %r9d,%r10d
  test   %r10b,%bl
  je     L44
  lea    (%r15,%r13,1),%r9
  add    %r8,%r9
  cmp    %r9,%rdx
  mov    -0x10(%rsp),%r9
  setb   %r10b
  add    %r15,%r9
  add    %r8,%r9
  cmp    %r9,%rdx
  seta   %r9b
  or     %r10b,%r9b
  je     L44
  mov    -0x1c(%rsp),%r11d
  movsd  (%rdx),%xmm2
  mov    %rsi,%r10
  xor    %r9d,%r9d
  xor    %ebx,%ebx
  shr    %r11d
  unpcklpd %xmm2,%xmm2
  mov    %r11d,%r12d
  mov    -0x18(%rsp),%r11
  add    %rax,%r11
  nopl   (%rax)
L147:
  movsd  0x8(%rax,%r9,1),%xmm0
  movsd  (%rax,%r9,1),%xmm1
  add    $0x1,%ebx
  movhpd (%rax,%r10,1),%xmm1
  movhpd 0x8(%rax,%r10,1),%xmm0
  subpd  %xmm1,%xmm0
  divpd  %xmm2,%xmm0
  movlpd %xmm0,(%r8,%r9,1)
  movhpd %xmm0,(%r8,%r10,1)
  movsd  0x8(%r11,%r9,1),%xmm0
  movsd  (%r11,%r9,1),%xmm1
  movhpd 0x8(%r11,%r10,1),%xmm0
  movhpd (%r11,%r10,1),%xmm1
  subpd  %xmm1,%xmm0
  divpd  %xmm2,%xmm0
  movlpd %xmm0,(%rdi,%r9,1)
  add    %rcx,%r9
  movhpd %xmm0,(%rdi,%r10,1)
  add    %rcx,%r10
  cmp    %r12d,%ebx
  jne    L147
  mov    -0x1c(%rsp),%ebx
  mov    %ebx,%r9d
  and    $0xfffffffe,%r9d
  mov    %r9d,%ecx
  imul   %rsi,%rcx
  lea    (%r8,%rcx,1),%rdi
  add    %rax,%rcx
  cmp    %r9d,%ebx
  je     L165
  movsd  0x8(%rcx),%xmm0
  subsd  (%rcx),%xmm0
  divsd  (%rdx),%xmm0
  movsd  %xmm0,(%rdi)
  movsd  -0x8(%rcx,%rsi,1),%xmm0
  subsd  -0x10(%rcx,%rsi,1),%xmm0
  divsd  (%rdx),%xmm0
  movsd  %xmm0,-0x8(%rdi,%rsi,1)
L165:
  cmp    $0x2,%r14d
  jle    L157
  lea    -0x2(%r14),%edi
  lea    -0x1(%r14),%ecx
  xor    %r12d,%r12d
  mov    %edi,%ebx
  lea    0x0(,%rcx,8),%r15
  mov    %edi,%ecx
  mov    %edi,-0x18(%rsp)
  shr    %ecx
  and    $0xfffffffe,%ebx
  lea    -0x3(%r14),%r13d
  or     $0x1,%edi
  movslq %edi,%rdi
  lea    -0x1(%rcx),%r9d
  mov    %ebx,-0x10(%rsp)
  lea    0x8(,%rdi,8),%r10
  add    $0x1,%r9
  shl    $0x3,%rdi
  shl    $0x4,%r9
  lea    -0x10(%r10),%r11
  nopl   0x0(%rax,%rax,1)
L221:
  lea    (%r8,%r15,1),%rcx
  cmp    %rcx,%rdx
  setae  %bl
  cmp    %r8,%rdx
  setbe  %cl
  or     %bl,%cl
  je     L193
  mov    %r8,%rcx
  sub    %rax,%rcx
  cmp    $0x10,%rcx
  seta   %bl
  cmp    $0x3,%r14d
  setne  %cl
  test   %cl,%bl
  je     L193
  movsd  (%rdx),%xmm1
  xor    %ecx,%ecx
  addsd  %xmm1,%xmm1
  unpcklpd %xmm1,%xmm1
  nopw   0x0(%rax,%rax,1)
L196:
  movupd 0x10(%rax,%rcx,1),%xmm0
  movupd (%rax,%rcx,1),%xmm3
  subpd  %xmm3,%xmm0
  divpd  %xmm1,%xmm0
  movups %xmm0,0x8(%r8,%rcx,1)
  add    $0x10,%rcx
  cmp    %rcx,%r9
  jne    L196
  mov    -0x10(%rsp),%ecx
  cmp    %ecx,-0x18(%rsp)
  je     L168
  movsd  (%rdx),%xmm1
  movsd  (%rax,%r10,1),%xmm0
  subsd  (%rax,%r11,1),%xmm0
  addsd  %xmm1,%xmm1
  divsd  %xmm1,%xmm0
  movsd  %xmm0,(%r8,%rdi,1)
L168:
  add    %rsi,%r8
  mov    %rbp,%rax
  add    $0x1,%r12d
  cmp    -0x1c(%rsp),%r12d
  je     L157
  add    %rsi,%rbp
  jmp    L221
  nop
L193:
  xor    %ecx,%ecx
  nopw   0x0(%rax,%rax,1)
L7:
  movsd  (%rdx),%xmm1
  movsd  0x10(%rax,%rcx,8),%xmm0
  mov    %rcx,%rbx
  subsd  (%rax,%rcx,8),%xmm0
  addsd  %xmm1,%xmm1
  divsd  %xmm1,%xmm0
  movsd  %xmm0,0x8(%r8,%rcx,8)
  add    $0x1,%rcx
  cmp    %rbx,%r13
  jne    L7
  jmp    L168
L80:
  mov    -0x1c(%rsp),%edi
  xor    %ecx,%ecx
  jmp    L212
  nopl   0x0(%rax)
L192:
  add    %rsi,%rbp
L212:
  add    $0x1,%ecx
  movsd  0x8(%rax),%xmm0
  subsd  (%rax),%xmm0
  divsd  (%rdx),%xmm0
  movsd  %xmm0,(%r8)
  movsd  -0x8(%rax,%rsi,1),%xmm0
  subsd  -0x10(%rax,%rsi,1),%xmm0
  mov    %rbp,%rax
  divsd  (%rdx),%xmm0
  movsd  %xmm0,-0x8(%r8,%rsi,1)
  add    %rsi,%r8
  cmp    %ecx,%edi
  jne    L192
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L44:
  mov    -0x1c(%rsp),%r10d
  mov    %rax,%rcx
  mov    %r8,%rdi
  xor    %r9d,%r9d
L13:
  add    $0x1,%r9d
  movsd  0x8(%rcx),%xmm0
  subsd  (%rcx),%xmm0
  divsd  (%rdx),%xmm0
  movsd  %xmm0,(%rdi)
  movsd  -0x8(%rcx,%rsi,1),%xmm0
  subsd  -0x10(%rcx,%rsi,1),%xmm0
  add    %rsi,%rcx
  divsd  (%rdx),%xmm0
  movsd  %xmm0,-0x8(%rdi,%rsi,1)
  add    %rsi,%rdi
  cmp    %r9d,%r10d
  jne    L13
  jmp    L165
```

assistant: ```c
void gradient(int *m, int *n, double *f, double *binsize, double *g) {
  int k, j;
  double *g_ptr, *f_ptr;
  g_ptr = g;
  f_ptr = f;
  for (k = 0; k < *n; k++) {
    g_ptr[0] = (f_ptr[1] - f_ptr[0]) / *binsize;
    g_ptr[*m - 1] = (f_ptr[*m - 1] - f_ptr[*m - 2]) / *binsize;
    g_ptr += *m;
    f_ptr += *m;
  }
  g_ptr = g;
  f_ptr = f;
  for (k = 0; k < *n; k++) {
    for (j = 1; j < *m - 1; j++)
      g_ptr[j] = (f_ptr[j + 1] - f_ptr[j - 1]) / (2.0 * *binsize);
    g_ptr += *m;
    f_ptr += *m;
  }
}
```