diff --git a/nemu/Makefile.git b/nemu/Makefile.git
index 47abe4a18edebbe4a76fb0d1a07aae50db60f69f..5a0091627052947e1ff905fa9508acc35928668a 100644
--- a/nemu/Makefile.git
+++ b/nemu/Makefile.git
@@ -3,7 +3,7 @@ STUNAME = 刘本嵩
 
 # DO NOT modify the following code!!!
 
-GITFLAGS = -q --author='tracer-ics2018 <tracer@njuics.org>' --no-verify --allow-empty
+GITFLAGS = -q
 
 # prototype: git_commit(msg)
 define git_commit_origin
diff --git a/nemu/src/monitor/debug/ui.cc b/nemu/src/monitor/debug/ui.cc
index 2b97f289ec97b4e1283cbd9d8d5e78f1c5370a19..75bc742d757e8cad7198e40afc6f14d310fe8ae2 100644
--- a/nemu/src/monitor/debug/ui.cc
+++ b/nemu/src/monitor/debug/ui.cc
@@ -7,6 +7,16 @@
 #include <readline/readline.h>
 #include <readline/history.h>
 
+#include <stdexcept>
+#include <rlib/stdio.hpp>
+using namespace rlib::literals;
+using rlib::println;
+using rlib::printfln;
+using rlib::string;
+
+#include <sstream>
+#include <iomanip>
+
 void cpu_exec(uint64_t);
 
 /* We use the `readline' library to provide more flexibility to read from stdin. */
@@ -116,7 +126,12 @@ void ui_mainloop(int is_batch_mode) {
     int i;
     for (i = 0; i < NR_CMD; i ++) {
       if (strcmp(cmd, cmd_table[i].name) == 0) {
-        if (cmd_table[i].handler(args) < 0) { return; }
+        try {
+          if (cmd_table[i].handler(args) < 0) { return; }
+        }
+        catch(std::exception &e) {
+          println("Exception caught:", e.what());
+        }
         break;
       }
     }
@@ -125,23 +140,25 @@ void ui_mainloop(int is_batch_mode) {
   }
 }
 
-#include <stdexcept>
-#include <rlib/stdio.hpp>
-using namespace rlib;
-using namespace rlib::literals;
-
-#include <sstream>
-#include <iomanip>
-
 auto dumpReg(uint32_t val) {
-  return string("{}{}[32b=0x{}{}, {}L16b=0x{}{}]").format(std::setfill('0'), std::setw(8), std::hex, val, std::setw(4), (uint16_t)val, std::dec);
+  return string("{}{}[32b=0x{}{}, {}L16b=0x{}]").format(std::setfill('0'), std::setw(8), std::hex, val, std::setw(4), (uint16_t)val);
 }
-
-static int cmd_info(char *args) {
-  if("r"_rs != args) {
-    println("Error: only 'info r' is supported.");
-    return 1;
+auto dumpMem(uint32_t begin_addr, uint64_t size) {
+  std::stringstream res;
+  res << std::hex;
+  for(uint64_t cter = 0; cter < size; cter += 4) {
+    if(cter % 32 == 0) {
+      res << '\n';
+      res << "0x" << std::setfill('0') << std::setw(8) << begin_addr + cter << ": ";
+    }
+    res << std::setfill('0') << std::setw(8) << vaddr_read(begin_addr + cter, 4) << ' ';
   }
+  return res.str();
+}
+
+static int cmd_info(char *_args) {
+  if(_args == NULL || "r"_rs != string(_args).strip())
+    throw std::runtime_error("Error: only 'info r' is supported.");
   println("Registers:");
   printfln("%eax={}, %ebx={}, %ecx={}, %edx={}", dumpReg(cpu.eax), dumpReg(cpu.ebx), dumpReg(cpu.ecx), dumpReg(cpu.edx));
   printfln("%esp={}, %ebp={}, %esi={}, %edi={}", dumpReg(cpu.esp), dumpReg(cpu.ebp), dumpReg(cpu.esi), dumpReg(cpu.edi));
@@ -149,6 +166,14 @@ static int cmd_info(char *args) {
   return 0;
 }
 
-static int cmd_x(char *args) {
+static int cmd_x(char *_args) {
+  if(_args == NULL)
+    throw std::runtime_error("Usage: x <size> <startAddr>");
+  auto args = string(_args).strip().split();
+  if(args.size() != 2)
+    throw std::runtime_error("Usage: x <size> <startAddr>");
+  
+  printfln("Dumping {}{} bytes from {}{}{}:{}", std::dec, args[0], std::hex, args[1], std::dec, dumpMem(std::stoull(args[1], 0, 16), args[0].as<uint64_t>()));
+  
   return 0;
 }
\ No newline at end of file