user: What is the c source code of the assembly code below?

```asm
<init_can>:
  endbr64
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  lea    D189(%rip),%rax
  cmp    %rax,%rdi
  je     L17
  mov    %rsi,%rbx
  lea    D198(%rip),%rax
  cmp    %rax,%rdi
  je     L40
L14:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  ret
L17:
  lea    D106(%rip),%rdi
  call   <puts@plt>
  lea    D176(%rip),%rdi
  call   <puts@plt>
  mov    $0xfffc0000,%ebx
  orb    $0x1,(%rbx)
  mov    $0xfffc001f,%edx
  movzbl (%rdx),%eax
  and    $0x78,%eax
  or     $0x7,%eax
  mov    %al,(%rdx)
  mov    $0xfffc0006,%eax
  movb   $0x83,(%rax)
  lea    0x1(%rax),%rax
  movb   $0x25,(%rax)
  lea    -0x3(%rax),%rax
  movb   $0x88,(%rax)
  lea    0x1(%rax),%rax
  movb   $0xff,(%rax)
  mov    $0x32,%edi
  call   <kill_time@plt>
  lea    D278(%rip),%rdi
  call   <puts@plt>
  andb   $0xfe,(%rbx)
  mov    $0x32,%edi
  call   <kill_time@plt>
  jmp    L14
L40:
  lea    D134(%rip),%rbp
  mov    %rbp,%rdi
  call   <puts@plt>
  lea    D2(%rip),%rdi
  call   <puts@plt>
  mov    %rbp,%rdi
  call   <puts@plt>
  lea    D176(%rip),%rdi
  call   <puts@plt>
  mov    $0xfffc0000,%eax
  movzbl (%rax),%esi
  or     $0x1,%esi
  mov    %sil,(%rax)
  movzbl %sil,%esi
  lea    D105(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0x32,%edi
  call   <kill_time@plt>
  lea    D59(%rip),%rdi
  call   <puts@plt>
  mov    $0xfffc001f,%eax
  movzbl (%rax),%esi
  or     $0xffffff87,%esi
  mov    %sil,(%rax)
  movzbl %sil,%esi
  lea    D210(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0x32,%edi
  call   <kill_time@plt>
  lea    D130(%rip),%rdi
  call   <puts@plt>
  lea    D279(%rip),%rdi
  call   <puts@plt>
  mov    $0xfffc0006,%eax
  movb   $0xa8,(%rax)
  mov    $0xa8,%esi
  lea    D41(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  lea    D200(%rip),%rdi
  call   <puts@plt>
  lea    D37(%rip),%rdi
  call   <puts@plt>
  mov    $0xfffc0007,%eax
  movb   $0x34,(%rax)
  mov    $0x34,%esi
  lea    D243(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  lea    D146(%rip),%rdi
  call   <puts@plt>
  mov    $0xfffc0010,%eax
  movb   $0xa6,(%rax)
  mov    $0xa6,%esi
  lea    D264(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xfffc0011,%eax
  movb   $0xb0,(%rax)
  mov    $0xb0,%esi
  lea    D215(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xfffc0012,%eax
  movb   $0x12,(%rax)
  mov    $0x12,%esi
  lea    D257(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xfffc0013,%eax
  movb   $0x30,(%rax)
  mov    $0x30,%esi
  lea    D252(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  lea    D100(%rip),%rdi
  call   <puts@plt>
  mov    $0xfffc0014,%eax
  movb   $0x0,(%rax)
  mov    $0x0,%esi
  lea    D230(%rip),%rbp
  mov    %rbp,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xfffc0015,%eax
  movb   $0x0,(%rax)
  mov    $0x0,%esi
  mov    %rbp,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xfffc0016,%eax
  movb   $0x0,(%rax)
  mov    $0x0,%esi
  mov    %rbp,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xfffc0017,%eax
  movb   $0x0,(%rax)
  mov    $0x0,%esi
  lea    D138(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  lea    D150(%rip),%rax
  cmp    %rax,%rbx
  je     L48
L10:
  lea    D278(%rip),%rdi
  call   <puts@plt>
  mov    $0xfffc0000,%eax
  movzbl (%rax),%esi
  and    $0xfffffffe,%esi
  mov    %sil,(%rax)
  movzbl %sil,%esi
  lea    D259(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0x32,%edi
  call   <kill_time@plt>
  jmp    L14
L48:
  mov    $0x0,%eax
  call   <self_testing_mode@plt>
  jmp    L10
```

tool_calls: name: extract_symbolic_data
arguments: data_label: D189
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D198
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D106
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D176
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D278
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D134
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D2
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D105
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D59
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D210
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D130
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D279
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D41
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D200
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D37
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D243
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D146
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D264
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D215
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D257
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D252
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D100
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D230
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D138
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D150
type_guessed: string
name: extract_symbolic_data
arguments: data_label: D259
type_guessed: string

tool: D189: Basic

tool: D198: Extended

tool: D106: ********** Basic Can Mode **********

tool: D176: Switch on Reset Mode

tool: D278: Switch off reset mode

tool: D134: ************************************

tool: D2: ******** Extended Can Mode *********

tool: D105: control_register: 0x%X 



tool: D59: Set clock divider register to extended can mode

tool: D210: clock_divider_register: 0x%X 



tool: D130: Set bus timing register 0

tool: D279: Sync Jump Width = 2  Baudrate Prescaler = 1

tool: D41: bus timing register 0: 0x%X 



tool: D200: Set bus timing register 1

tool: D37: SAM = 0 ---> Single Sampling

tool: D243: bus timing register 1: 0x%X 



tool: D146: Set acceptance code register

tool: D264: acceptance code register 0: 0x%X 


tool: D215: acceptance code register 1: 0x%X 


tool: D257: acceptance code register 2: 0x%X 


tool: D252: acceptance code register 3: 0x%X 



tool: D100: Set acceptance mask register

tool: D230: acceptance mask register: 0x%X 


tool: D138: acceptance mask register: 0x%X 



tool: D150: self_test

tool: D259: control_register 0x%X 



assistant: ```c
void init_can(char *mode, char *self_test) {
  unsigned char r_val;
  if (mode == "Basic") {
    printf("********** Basic Can Mode **********\n");
    printf("Switch on Reset Mode\n");
    r_val = *((unsigned char *)(0xfffc0000 + 0x0000)) | 0x01;
    *((unsigned char *)(0xfffc0000 + 0x0000)) = r_val;
    r_val = *((unsigned char *)(0xfffc0000 + 0x001F)) & 0x7F | 0x07;
    *((unsigned char *)(0xfffc0000 + 0x001F)) = r_val;
    *((unsigned char *)(0xfffc0000 + 0x0006)) = 0x83;
    *((unsigned char *)(0xfffc0000 + 0x0007)) = 0x25;
    *((unsigned char *)(0xfffc0000 + 0x0004)) = 0x88;
    *((unsigned char *)(0xfffc0000 + 0x0005)) = 0xFF;
    kill_time(50);
    printf("Switch off reset mode\n");
    r_val = *((unsigned char *)(0xfffc0000 + 0x0000)) & 0xFE;
    *((unsigned char *)(0xfffc0000 + 0x0000)) = r_val;
    kill_time(50);
  } else if (mode == "Extended") {
    printf("************************************\n");
    printf("******** Extended Can Mode *********\n");
    printf("************************************\n");
    printf("Switch on Reset Mode\n");
    r_val = *((unsigned char *)(0xfffc0000 + 0x0000)) | 0x01;
    *((unsigned char *)(0xfffc0000 + 0x0000)) = r_val;
    printf("control_register: 0x%X \n\n", *((unsigned char *)(0xfffc0000 + 0x0000)));
    kill_time(50);
    printf("Set clock divider register to extended can mode\n");
    r_val = *((unsigned char *)(0xfffc0000 + 0x001F)) | 0x80 | 0x07;
    *((unsigned char *)(0xfffc0000 + 0x001F)) = r_val;
    printf("clock_divider_register: 0x%X \n\n", *((unsigned char *)(0xfffc0000 + 0x001F)));
    kill_time(50);
    printf("Set bus timing register 0\n");
    printf("Sync Jump Width = 2  Baudrate Prescaler = 1\n");
    *((unsigned char *)(0xfffc0000 + 0x0006)) = 0xA8;
    printf("bus timing register 0: 0x%X \n\n", *((unsigned char *)(0xfffc0000 + 0x0006)));
    printf("Set bus timing register 1\n");
    printf("SAM = 0 ---> Single Sampling\n");
    *((unsigned char *)(0xfffc0000 + 0x0007)) = 0x34;
    printf("bus timing register 1: 0x%X \n\n", *((unsigned char *)(0xfffc0000 + 0x0007)));
    printf("Set acceptance code register\n");
    *((unsigned char *)(0xfffc0000 + 0x0010)) = 0xA6;
    printf("acceptance code register 0: 0x%X \n", *((unsigned char *)(0xfffc0000 + 0x0010)));
    *((unsigned char *)(0xfffc0000 + 0x0011)) = 0xB0;
    printf("acceptance code register 1: 0x%X \n", *((unsigned char *)(0xfffc0000 + 0x0011)));
    *((unsigned char *)(0xfffc0000 + 0x0012)) = 0x12;
    printf("acceptance code register 2: 0x%X \n", *((unsigned char *)(0xfffc0000 + 0x0012)));
    *((unsigned char *)(0xfffc0000 + 0x0013)) = 0x30;
    printf("acceptance code register 3: 0x%X \n\n", *((unsigned char *)(0xfffc0000 + 0x0013)));
    printf("Set acceptance mask register\n");
    *((unsigned char *)(0xfffc0000 + 0x0014)) = 0x00;
    printf("acceptance mask register: 0x%X \n", *((unsigned char *)(0xfffc0000 + 0x0014)));
    *((unsigned char *)(0xfffc0000 + 0x0015)) = 0x00;
    printf("acceptance mask register: 0x%X \n", *((unsigned char *)(0xfffc0000 + 0x0015)));
    *((unsigned char *)(0xfffc0000 + 0x0016)) = 0x00;
    printf("acceptance mask register: 0x%X \n", *((unsigned char *)(0xfffc0000 + 0x0016)));
    *((unsigned char *)(0xfffc0000 + 0x0017)) = 0x00;
    printf("acceptance mask register: 0x%X \n\n", *((unsigned char *)(0xfffc0000 + 0x0017)));
    if (self_test == "self_test") {
      self_testing_mode();
    }
    printf("Switch off reset mode\n");
    r_val = *((unsigned char *)(0xfffc0000 + 0x0000)) & 0xFE;
    *((unsigned char *)(0xfffc0000 + 0x0000)) = r_val;
    printf("control_register 0x%X \n\n", *((unsigned char *)(0xfffc0000 + 0x0000)));
    kill_time(50);
  }
}
```