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

```asm
<sh>:
  endbr64
  push   %r15
  push   %r14
  lea    D27(%rip),%r14
  push   %r13
  mov    %edi,%r13d
  push   %r12
  push   %rbp
  push   %rbx
  mov    %esi,%ebx
  sub    $0x8,%rsp
  jmp    L93
  nopl   0x0(%rax,%rax,1)
L42:
  mov    %r13d,%edi
  xor    %eax,%eax
  call   <readline@plt>
  movslq %eax,%rbp
  test   %eax,%eax
  je     L135
  mov    %rbp,%rdi
  call   <strlen@plt>
  mov    %rbp,%rdi
  mov    %rax,%rsi
  xor    %eax,%eax
  call   <tokenize@plt>
  movslq %eax,%r12
  test   %eax,%eax
  je     L2
  mov    (%r12),%r15
  test   %r15,%r15
  je     L27
  mov    %r14,%rsi
  mov    %r15,%rdi
  call   <strcmp@plt>
  test   %eax,%eax
  je     L37
  cmpb   $0x63,(%r15)
  je     L173
L148:
  call   <fork@plt>
  test   %eax,%eax
  je     L56
  xor    %edi,%edi
  xor    %eax,%eax
  call   <wait@plt>
  nopl   0x0(%rax)
L27:
  mov    %rbp,%rdi
  call   <free@plt>
  mov    %r12,%rdi
  call   <free@plt>
L93:
  test   %ebx,%ebx
  je     L42
  lea    D58(%rip),%rsi
  mov    $0x1,%edi
  xor    %eax,%eax
  call   <writestr@plt>
  jmp    L42
  nopl   0x0(%rax,%rax,1)
L2:
  lea    D49(%rip),%rsi
  mov    $0x2,%edi
  call   <writestr@plt>
  jmp    L27
  nopl   0x0(%rax,%rax,1)
L173:
  cmpb   $0x64,0x1(%r15)
  jne    L148
  cmpb   $0x0,0x2(%r15)
  jne    L148
  mov    0x8(%r12),%rdi
  test   %rdi,%rdi
  je     L35
  xor    %eax,%eax
  call   <chdir@plt>
  jmp    L27
  nopl   0x0(%rax)
L35:
  xor    %eax,%eax
  lea    D7(%rip),%rdi
  call   <getenv@plt>
  test   %eax,%eax
  jne    L131
  lea    D57(%rip),%rdi
  call   <chdir@plt>
  jmp    L27
  nopl   0x0(%rax,%rax,1)
L37:
  mov    0x8(%r12),%rdi
  test   %rdi,%rdi
  jne    L28
L135:
  add    $0x8,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax,%rax,1)
L131:
  movslq %eax,%rdi
  xor    %eax,%eax
  call   <chdir@plt>
  jmp    L27
L28:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    11b0 <atoi@plt>
L56:
  mov    (%r12),%rdi
  mov    %r12,%rsi
  call   <execvp@plt>
  lea    D56(%rip),%rsi
  mov    $0x2,%edi
  xor    %eax,%eax
  call   <writestr@plt>
  mov    (%r12),%rsi
  mov    $0x2,%edi
  xor    %eax,%eax
  call   <writestr@plt>
  mov    $0x2,%edi
  lea    D66(%rip),%rsi
  xor    %eax,%eax
  call   <writestr@plt>
  mov    $0xff,%edi
  call   <_exit@plt>
```

tool_calls: name: retrieve_data
arguments: data_tag: D27
type_guessed: string
name: retrieve_data
arguments: data_tag: D58
type_guessed: string
name: retrieve_data
arguments: data_tag: D49
type_guessed: string
name: retrieve_data
arguments: data_tag: D7
type_guessed: string
name: retrieve_data
arguments: data_tag: D57
type_guessed: string
name: retrieve_data
arguments: data_tag: D56
type_guessed: string
name: retrieve_data
arguments: data_tag: D66
type_guessed: string

tool: D27: exit

tool: D58: $ 

tool: D49: sh: Syntax error


tool: D7: HOME

tool: D57: /

tool: D56: sh: 

tool: D66: : Not found


assistant: ```c
int sh(int f, int interactive) {
  char *line, **newargv, *tmpstr;
  for (;;) {
    if (interactive)
      writestr(1, "$ ");
    if ((line = readline(f)) == 0)
      return 0;
    if ((newargv = tokenize(line, strlen(line))) == 0)
      writestr(2, "sh: Syntax error\n");
    else if (*newargv != 0) {
      if (!strcmp(newargv[0], "exit")) {
        if (newargv[1] == 0)
          return 0;
        else
          return atoi(newargv[1]);
      } else if (!strcmp(newargv[0], "cd")) {
        if (newargv[1] == 0) {
          if ((tmpstr = getenv("HOME")) == 0)
            chdir("/");
          else
            chdir(tmpstr);
        } else
          chdir(newargv[1]);
      } else {
        if (fork())
          wait(0);
        else {
          execvp(newargv[0], newargv);
          writestr(2, "sh: ");
          writestr(2, newargv[0]);
          writestr(2, ": Not found\n");
          _exit(255);
        }
      }
    }
    free(line);
    line = 0;
    free(newargv);
    newargv = 0;
  }
  return 0;
}
```