ICS2020 简易调试器(一)

本实验目的是实现一个类似GDB的简易调试器

已实现命令--help, c, q

这次实现了si, info。如图:

ICS2020 简易调试器(一)

单步执行:

(添加指令和对应描述过程略)

首先完成单步执行命令,包括两个参数--代表单步执行命令的si与需要执行指令个数N

参考cmd_help读取第二个参数的写法:

static int cmd_help(char *args) {
  /* extract the first argument */
  char *arg = strtok(NULL, " ");
  int i;

  if (arg == NULL) {
    /* no argument given */
    for (i = 0; i < NR_CMD; i ++) {
      printf("%s - %s\n", cmd_table[i].name, cmd_table[i].description);
    }
  }
  else {
    for (i = 0; i < NR_CMD; i ++) {
      if (strcmp(arg, cmd_table[i].name) == 0) {
        printf("%s - %s\n", cmd_table[i].name, cmd_table[i].description);
        return 0;
      }
    }
    printf("Unknown command '%s'\n", arg);
  }
  return 0;
}

可知arg用来存储help后面的参数。再验证一下:

ICS2020 简易调试器(一)

照着写一个读取命令行参数,N读取问题解决。再写一个字符串转数字,将N放入cpu_exec(n),cmd_si()函数完成~

static int cmd_si(char *args){
  /* extract the first argument */
  char *arg = strtok(NULL, " ");
  uint64_t n = 0;
  char ch;
  //判断有无输入N,若无N参数则默认为1
  if(arg == NULL)
  {
    cpu_exec(1);
    return 0;
  }
  //取数字N
  while(*arg != '\0')
  {
    ch = *arg++;
    if(ch < '0'|| ch > '9')
    {
      printf("Wrong si N! Error!\n");
      return 0;
    }
    n = n * 10 + (ch - '0');
  }
  if(n == 0) n=1;
  cpu_exec(n);
  return 0;
}

打印寄存器状态:

cmd_info()也参照上面的完成:

static int cmd_info(char *args){
  /* extract the first argument */
  char *arg = strtok(NULL, " ");
  if(arg == NULL) return 0;
  else if (strcmp(arg, "r") == 0)
    isa_reg_display();
  else if (strcmp(arg, "w") == 0)
    //还不知道怎么写
    printf("Info w: incomplete;\n");
  else
  {
    printf("You should give r/w after info!\n");
    return 0;
  }
  return 0;
}

但是发现isa_reg_display()是空的,需要完善

参考PA给的寄存器,定义寄存器3*8个

rtlreg_t eax, ecx, edx, ebx, esp, ebp, esi, edi;
uint16_t ax, cx, dx, bx, sp, bp, si, di;
uint8_t al, cl, dl, bl, ah, ch, dh, bh;

查找关于cpu存寄存器的情况,发现只存了第一排的32位寄存器的内容二三排则没有:

ICS2020 简易调试器(一)

推测通过32位取低位放入这些寄存器中,且有写好取低位

ICS2020 简易调试器(一)

那么最后一个函数也完成了:

/**
 * @brief TODO: 打印寄存器
 * 
 */
void isa_reg_display() {
  rtlreg_t eax, ecx, edx, ebx, esp, ebp, esi, edi;
  uint16_t ax, cx, dx, bx, sp, bp, si, di;
  uint8_t al, cl, dl, bl, ah, ch, dh, bh;
  eax = cpu.eax;
  ecx = cpu.ecx;
  edx = cpu.edx;
  ebx = cpu.ebx;
  esp = cpu.esp;
  ebp = cpu.ebp;
  esi = cpu.esi;
  edi = cpu.edi;
  //打印8个寄存器
  printf("EAX: %#010x, ECX: %#010x, EDX: %#010x, EBX: %#010x, \nESP: %#010x, EBP: %#010x, ESI: %#010x, EDI: %#010x\n", eax, ecx, edx, ebx, esp, ebp, esi, edi);

  ax = reg_w(R_AX);
  cx = reg_w(R_CX);
  dx = reg_w(R_DX);
  bx = reg_w(R_BX);
  sp = reg_w(R_SP);
  bp = reg_w(R_BP);
  si = reg_w(R_SI);
  di = reg_w(R_DI);
  //打印8个寄存器
  printf("AX: %#010x, CX: %#010x, DX: %#010x, BX: %#010x, \nSP: %#010x, BP: %#010x, SI: %#010x, DI: %#010x\n", ax, cx, dx, bx, sp, bp, si, di);

  al = reg_b(R_AL);
  cl = reg_b(R_CL);
  dl = reg_b(R_DL);
  bl = reg_b(R_BL);
  ah = reg_b(R_AH);
  ch = reg_b(R_CH);
  dh = reg_b(R_DH);
  bh = reg_b(R_BH);
  //打印8个寄存器
  printf("AL: %#010x, CL: %#010x, DL: %#010x, BL: %#010x, \nAH: %#010x, CH: %#010x, DH: %#010x, BH: %#010x\n", al, cl, dl, bl, ah, ch, dh, bh);

}

那么对这次写的功能进行测试:

ICS2020 简易调试器(一)

结束!

上一篇:AQS-ReentrantLock.CountDownLatch 源码


下一篇:[JSOI2008]魔兽地图DotR 做题心得