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

```asm
<string_replace_regex_get_replace>:
  endbr64
  push   %r15
  push   %r14
  mov    %rcx,%r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,0x28(%rsp)
  mov    %rsi,0x18(%rsp)
  mov    %edx,0x24(%rsp)
  mov    %r8b,0x23(%rsp)
  call   <strlen@plt>
  lea    (%rax,%rax,1),%ebp
  lea    0x1(%rbp),%edi
  call   <malloc@plt>
  mov    %rax,%r12
  test   %rax,%rax
  je     L4
  movb   $0x0,(%rax)
  xor    %ebx,%ebx
  test   %r14,%r14
  je     L4
  nopw   0x0(%rax,%rax,1)
L291:
  movzbl (%r14),%eax
  test   %al,%al
  je     L4
L210:
  cmp    $0x5c,%al
  je     L345
L335:
  cmp    0x23(%rsp),%al
  jne    L350
  movzbl 0x1(%r14),%edi
  cmp    $0x2b,%dil
  jne    L109
L344:
  mov    0x24(%rsp),%eax
  add    $0x2,%r14
L30:
  cltq
  shl    $0x4,%rax
  add    0x18(%rsp),%rax
  mov    (%rax),%r9
  test   %r9,%r9
  js     L291
  mov    0x8(%rax),%edx
  xor    %r15d,%r15d
  sub    %r9d,%edx
  add    0x28(%rsp),%r9
  je     L291
L243:
  lea    (%rbx,%rdx,1),%r13d
  cmp    %ebp,%r13d
  jle    L192
  add    %ebp,%ebp
  mov    %r12,%rdi
  mov    %r9,0x10(%rsp)
  cmp    %ebp,%r13d
  mov    %edx,0x8(%rsp)
  cmovge %r13d,%ebp
  lea    0x1(%rbp),%esi
  call   <realloc@plt>
  mov    0x8(%rsp),%edx
  mov    0x10(%rsp),%r9
  test   %rax,%rax
  je     L98
  mov    %rax,%r12
L192:
  movslq %ebx,%rdi
  mov    %r9,%rsi
  mov    %r13d,%ebx
  add    %r12,%rdi
  call   <memcpy@plt>
  movslq %r13d,%rax
  movb   $0x0,(%r12,%rax,1)
  test   %r15,%r15
  je     L291
  mov    %r15,%rdi
  call   <free@plt>
  movzbl (%r14),%eax
  test   %al,%al
  jne    L210
L4:
  add    $0x38,%rsp
  mov    %r12,%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax,%rax,1)
L350:
  mov    %r14,%rdi
  xor    %r15d,%r15d
  call   <utf8_char_size@plt>
  mov    %r14,%r9
  mov    %eax,%edx
  cltq
  add    %rax,%r14
  jmp    L243
  nopw   0x0(%rax,%rax,1)
L345:
  movzbl 0x23(%rsp),%ecx
  cmp    %cl,0x1(%r14)
  jne    L335
  lea    0x1(%r14),%r9
  xor    %r15d,%r15d
  add    $0x2,%r14
  mov    $0x1,%edx
  jmp    L243
  nopl   0x0(%rax)
L109:
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L178
  cmpb   $0x2e,0x1(%r14)
  je     L65
L303:
  add    $0x1,%r14
  jmp    L291
  nopw   0x0(%rax,%rax,1)
L178:
  cmpb   $0x2b,0x1(%r14)
  je     L344
  movzbl 0x2(%r14),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  movsbl 0x1(%r14),%eax
  je     L61
  lea    -0xf0(%rax,%rax,4),%edx
  movsbl 0x2(%r14),%eax
  add    $0x3,%r14
  lea    -0x30(%rax,%rdx,2),%eax
  jmp    L30
  nopl   0x0(%rax,%rax,1)
L61:
  sub    $0x30,%eax
  add    $0x2,%r14
  jmp    L30
  nopl   0x0(%rax)
L65:
  movzbl 0x2(%r14),%r15d
  lea    -0x20(%r15),%eax
  cmp    $0x5e,%al
  ja     L303
  movzbl 0x3(%r14),%eax
  cmp    $0x2b,%al
  jne    L180
L108:
  mov    0x24(%rsp),%eax
  add    $0x4,%r14
L3:
  cltq
  shl    $0x4,%rax
  add    0x18(%rsp),%rax
  mov    (%rax),%rdx
  test   %rdx,%rdx
  js     L291
  mov    0x8(%rax),%esi
  mov    0x28(%rsp),%rax
  sub    %edx,%esi
  lea    (%rax,%rdx,1),%rdi
  call   <string_strndup@plt>
  mov    %rax,%r13
  test   %rax,%rax
  je     L291
  mov    %rax,%rdi
  call   <utf8_strlen@plt>
  lea    0x1(%rax),%edi
  mov    %eax,0x8(%rsp)
  call   <malloc@plt>
  mov    0x8(%rsp),%edx
  test   %rax,%rax
  je     L300
  movsbl %r15b,%esi
  mov    %rax,%rdi
  mov    %edx,0x10(%rsp)
  mov    %rax,0x8(%rsp)
  call   <memset@plt>
  mov    0x8(%rsp),%r9
  movslq 0x10(%rsp),%rax
  mov    %r13,%rdi
  movb   $0x0,(%r9,%rax,1)
  call   <free@plt>
  mov    0x8(%rsp),%r9
  mov    0x10(%rsp),%edx
  mov    %r9,%r15
  jmp    L243
  cs nopw 0x0(%rax,%rax,1)
L98:
  test   %r15,%r15
  je     L270
  mov    %r15,%rdi
  call   <free@plt>
L270:
  mov    %r12,%rdi
  xor    %r12d,%r12d
  call   <free@plt>
  jmp    L4
L180:
  movzbl %al,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L303
  cmpb   $0x2b,0x3(%r14)
  movzbl 0x2(%r14),%r15d
  je     L108
  movzbl 0x4(%r14),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  movsbl 0x3(%r14),%eax
  je     L324
  lea    -0xf0(%rax,%rax,4),%edx
  movsbl 0x4(%r14),%eax
  add    $0x5,%r14
  lea    -0x30(%rax,%rdx,2),%eax
  jmp    L3
L324:
  sub    $0x30,%eax
  add    $0x4,%r14
  jmp    L3
L300:
  mov    %r13,%rdi
  call   <free@plt>
  jmp    L291
```

assistant: ```c
char *string_replace_regex_get_replace(const char *string, regmatch_t *regex_match, int last_match, const char *replace, const char reference_char) {
  int length, length_current, length_add, match;
  const char *ptr_replace, *ptr_add;
  char *result, *result2, *modified_replace, *temp, char_replace;
  length = (strlen(string) * 2);
  result = malloc(length + 1);
  if (!result)
    return NULL;
  result[0] = '\0';
  length_current = 0;
  ptr_replace = replace;
  while (ptr_replace && ptr_replace[0]) {
    ptr_add = NULL;
    length_add = 0;
    modified_replace = NULL;
    if ((ptr_replace[0] == '\\') && (ptr_replace[1] == reference_char)) {
      ptr_add = ptr_replace + 1;
      length_add = 1;
      ptr_replace += 2;
    } else if (ptr_replace[0] == reference_char) {
      if ((ptr_replace[1] == '+') || isdigit((unsigned char)ptr_replace[1])) {
        if (ptr_replace[1] == '+') {
          match = last_match;
          ptr_replace += 2;
        } else {
          if (isdigit((unsigned char)ptr_replace[2])) {
            match = ((ptr_replace[1] - '0') * 10) + (ptr_replace[2] - '0');
            ptr_replace += 3;
          } else {
            match = ptr_replace[1] - '0';
            ptr_replace += 2;
          }
        }
        if (regex_match[match].rm_so >= 0) {
          ptr_add = string + regex_match[match].rm_so;
          length_add = regex_match[match].rm_eo - regex_match[match].rm_so;
        }
      } else if ((ptr_replace[1] == '.') && (ptr_replace[2] >= 32) && (ptr_replace[2] <= 126) && ((ptr_replace[3] == '+') || isdigit((unsigned char)ptr_replace[3]))) {
        char_replace = ptr_replace[2];
        if (ptr_replace[3] == '+') {
          match = last_match;
          ptr_replace += 4;
        } else {
          if (isdigit((unsigned char)ptr_replace[4])) {
            match = ((ptr_replace[3] - '0') * 10) + (ptr_replace[4] - '0');
            ptr_replace += 5;
          } else {
            match = ptr_replace[3] - '0';
            ptr_replace += 4;
          }
        }
        if (regex_match[match].rm_so >= 0) {
          temp = string_strndup(string + regex_match[match].rm_so, regex_match[match].rm_eo - regex_match[match].rm_so);
          if (temp) {
            length_add = utf8_strlen(temp);
            modified_replace = malloc(length_add + 1);
            if (modified_replace) {
              memset(modified_replace, char_replace, length_add);
              modified_replace[length_add] = '\0';
              ptr_add = modified_replace;
            }
            free(temp);
          }
        }
      } else {
        ptr_replace++;
      }
    } else {
      ptr_add = ptr_replace;
      length_add = utf8_char_size(ptr_replace);
      ptr_replace += length_add;
    }
    if (ptr_add) {
      if (length_current + length_add > length) {
        length = (length * 2 >= length_current + length_add) ? length * 2 : length_current + length_add;
        result2 = realloc(result, length + 1);
        if (!result2) {
          if (modified_replace)
            free(modified_replace);
          free(result);
          return NULL;
        }
        result = result2;
      }
      memcpy(result + length_current, ptr_add, length_add);
      length_current += length_add;
      result[length_current] = '\0';
    }
    if (modified_replace)
      free(modified_replace);
  }
  return result;
}
```