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

```asm
<extend_plane_borders>:
  endbr64
  push   %r15
  mov    %rdi,%rax
  push   %r14
  push   %r13
  push   %r12
  mov    %r9d,%r12d
  push   %rbp
  push   %rbx
  movslq %ecx,%rbx
  lea    -0x1(%rdi,%rbx,1),%rbp
  add    %rdi,%rbx
  sub    $0x48,%rsp
  mov    %ecx,0x3c(%rsp)
  movslq %r9d,%rcx
  sub    %rcx,%rax
  mov    %rdi,0x20(%rsp)
  mov    %esi,0x1c(%rsp)
  mov    %edx,0x8(%rsp)
  mov    %r8d,0x38(%rsp)
  mov    %rcx,0x30(%rsp)
  mov    %rax,0x28(%rsp)
  test   %edx,%edx
  js     L42
  movslq 0x1c(%rsp),%rcx
  mov    %r9d,0x10(%rsp)
  xor    %r13d,%r13d
  mov    0x28(%rsp),%r15
  mov    0x20(%rsp),%r14
  mov    %r13d,%r12d
  mov    %rbx,%r13
  mov    %rcx,%rbx
  nopl   (%rax)
L5:
  movzbl (%r14),%esi
  mov    0x10(%rsp),%edx
  mov    %r15,%rdi
  add    %rbx,%r14
  add    %rbx,%r15
  add    $0x1,%r12d
  call   <memset@plt>
  movzbl 0x0(%rbp),%esi
  mov    %r13,%rdi
  add    %rbx,%rbp
  mov    0x88(%rsp),%edx
  add    %rbx,%r13
  call   <memset@plt>
  cmp    %r12d,0x8(%rsp)
  jge    L5
  mov    0x10(%rsp),%r12d
L42:
  mov    0x8(%rsp),%eax
  mov    0x38(%rsp),%edi
  xor    %r13d,%r13d
  mov    0x1c(%rsp),%edx
  mov    0x30(%rsp),%r10
  sub    $0x1,%eax
  mov    %edi,%ecx
  mov    0x20(%rsp),%rsi
  add    0x88(%rsp),%r12d
  imul   %edx,%eax
  neg    %ecx
  movslq %edx,%r14
  imul   %edx,%ecx
  lea    (%rax,%r14,1),%ebp
  movslq %eax,%rbx
  mov    0x3c(%rsp),%eax
  movslq %ecx,%rcx
  movslq %ebp,%rbp
  sub    %r10,%rbx
  sub    %r10,%rcx
  sub    %r10,%rbp
  lea    0x1(%rax,%r12,1),%r12d
  add    %rsi,%rbx
  lea    (%rsi,%rcx,1),%r15
  add    %rsi,%rbp
  test   %edi,%edi
  jle    L25
  mov    %rbx,0x8(%rsp)
  mov    %r15,%rbx
  mov    0x38(%rsp),%r15d
  mov    %rbp,0x10(%rsp)
  mov    %r13d,%ebp
  mov    0x28(%rsp),%r13
  nopw   0x0(%rax,%rax,1)
L3:
  mov    %rbx,%rdi
  mov    %r12d,%edx
  mov    %r13,%rsi
  add    $0x1,%ebp
  call   <memcpy@plt>
  add    %r14,%rbx
  cmp    %ebp,%r15d
  jne    L3
  mov    0x8(%rsp),%rbx
  mov    0x10(%rsp),%rbp
L25:
  mov    0x80(%rsp),%eax
  movslq 0x1c(%rsp),%r14
  xor    %r13d,%r13d
  mov    0x80(%rsp),%r15d
  test   %eax,%eax
  jle    L50
  xchg   %ax,%ax
L22:
  mov    %rbp,%rdi
  mov    %r12d,%edx
  mov    %rbx,%rsi
  add    $0x1,%r13d
  call   <memcpy@plt>
  add    %r14,%rbp
  cmp    %r13d,%r15d
  jne    L22
L50:
  add    $0x48,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

assistant: ```c
void extend_plane_borders(unsigned char *s, int sp, int h, int w, int et, int el, int eb, int er) {
  int i;
  unsigned char *src_ptr1, *src_ptr2;
  unsigned char *dest_ptr1, *dest_ptr2;
  int linesize;
  src_ptr1 = s;
  src_ptr2 = s + w - 1;
  dest_ptr1 = s - el;
  dest_ptr2 = s + w;
  for (i = 0; i < h - 0 + 1; i++) {
    memset(dest_ptr1, src_ptr1[0], el);
    memset(dest_ptr2, src_ptr2[0], er);
    src_ptr1 += sp;
    src_ptr2 += sp;
    dest_ptr1 += sp;
    dest_ptr2 += sp;
  }
  src_ptr1 = s - el;
  src_ptr2 = s + sp * (h - 1) - el;
  dest_ptr1 = s + sp * (-et) - el;
  dest_ptr2 = s + sp * (h)-el;
  linesize = el + er + w + 1;
  for (i = 0; i < (int)et; i++) {
    memcpy(dest_ptr1, src_ptr1, linesize);
    dest_ptr1 += sp;
  }
  for (i = 0; i < (int)eb; i++) {
    memcpy(dest_ptr2, src_ptr2, linesize);
    dest_ptr2 += sp;
  }
}
```