DoctorWkt / acwj

A Compiler Writing Journey
GNU General Public License v3.0
10.55k stars 1.02k forks source link

Segment Fault in Part 15 #29

Closed alex-xia-xia closed 4 years ago

alex-xia-xia commented 4 years ago

cg.c line 80

// Load a value from a variable into a register.
// Return the number of the register
int cgloadglob(int id) {
  // Get a new register
  int r = alloc_register();

  // Print out the code to initialise it
  switch (Gsym[id].type) {
    case P_CHAR:
      fprintf(Outfile, "\tmovzbq\t%s(%%rip), %s\n", Gsym[id].name,
          reglist[r]);
      break;
    case P_INT:
      fprintf(Outfile, "\tmovzbl\t%s(\%%rip), %s\n", Gsym[id].name,
          reglist[r]);
      break;
    case P_LONG:
    case P_CHARPTR:
    case P_INTPTR:
    case P_LONGPTR:
      fprintf(Outfile, "\tmovq\t%s(\%%rip), %s\n", Gsym[id].name, reglist[r]);
      break;
    default:
      fatald("Bad type in cgloadglob:", Gsym[id].type);
  }
  return (r);
}

When I run this code. It got segment faults. The code above always used 64bit register for any type variables. Type P_CHAR maybe should use movb instruction to load from global to breglist[r], or use movzbq to reglist[r]. Type P_INT maybe should use movl instruction to load from global to *dreglist[r].

Or if you want to call printint(long), mov dreglist[r] to %rdi, maybe you need instruction cltq. I think there maybe some errors in this function. It maybe be

// load a value from a variable into a register.
// return the number of the register
int cgloadglob(int id) {
  // get a new register
  int r = alloc_register();

  // print out the code to initialize it
  switch (Gsym[id].type) {
    case P_CHAR:
      fprintf(Outfile, "\tmovzbq\t%s(\%%rip), %s\n", Gsym[id].name, reglist[r]);
      break;
    case P_INT:
      fprintf(Outfile, "\tmovl\t%s(\%%rip), %s\n", Gsym[id].name, dreglist[r]);
      fprintf(Outfile, "\tcltq\n");
      break;
    case P_LONG:
    case P_CHARPTR:
    case P_INTPTR:
    case P_LONGPTR:
      fprintf(Outfile, "\tmovq\t%s(\%%rip), %s\n", Gsym[id].name, reglist[r]);
      break;
    default:
      fatald("Bad type in cgloadglob:", Gsym[id].type);
  }

  return r;
}

Thanks!