diff --git a/nemu/src/cpu/exec/arith.cc b/nemu/src/cpu/exec/arith.cc
index fb376f94bcffbcabe9d546e04c8c844c924af81c..7fbd98cf98ba34a72f12a2f06b8ca75466183940 100644
--- a/nemu/src/cpu/exec/arith.cc
+++ b/nemu/src/cpu/exec/arith.cc
@@ -42,7 +42,7 @@ namespace EHelperImpl {
   
   
   make_EHelper(cmp) {
-    rlib::println("debug: cmp: id_dest=", *id_dest, ", id_src=", *id_src);
+    // rlib::println("debug: cmp: id_dest=", *id_dest, ", id_src=", *id_src);
   	rtl_sext(&t1, &id_dest->val, id_dest->width);
   	rtl_sext(&t2, &id_src->val, id_src->width);
   
diff --git a/nemu/src/cpu/exec/data-mov.cc b/nemu/src/cpu/exec/data-mov.cc
index 8e61839b7d80aaf0eec3ebb10bf4e299950259b8..78d7a61d8ef288ed240114bb733b045ba798a11b 100644
--- a/nemu/src/cpu/exec/data-mov.cc
+++ b/nemu/src/cpu/exec/data-mov.cc
@@ -62,11 +62,13 @@ namespace EHelperImpl {
   }
   
   make_EHelper(cltd) {
+    // r: dbt
     if (decoding.is_operand_size_16) {
-      TODO();
+      rtl_sext(&t0, &reg_l(R_EAX), 2);
+      rtl_shri(&reg_l(R_EDX), &t0, 16);
     }
     else {
-      TODO();
+      rtl_sari(&reg_l(R_EDX), &reg_l(R_EAX), 31);
     }
   
     print_asm(decoding.is_operand_size_16 ? "cwtl" : "cltd");
diff --git a/nemu/src/cpu/exec/logic.cc b/nemu/src/cpu/exec/logic.cc
index 764b95e172458912e9436ae50ebbaf5c178f867a..151e21074adf23cb492d09279501d5b6538cbbf9 100644
--- a/nemu/src/cpu/exec/logic.cc
+++ b/nemu/src/cpu/exec/logic.cc
@@ -4,14 +4,11 @@
 void sign_extend_if_required(const Operand &dest, Operand &src) {
   if(dest.width > src.width) {
     rtl_sext(&src.val, &src.val, src.width);
-    src.imm = src.val;
     src.width = dest.width;
   }
 }
 
 namespace EHelperImpl {
-  using vaddr_t = uint32_t;
-
   make_EHelper(test) {
     // `and` without write_back.
     sign_extend_if_required(*id_dest, *id_src);
@@ -24,9 +21,9 @@ namespace EHelperImpl {
   }
   
   make_EHelper(and_) {
-    rlib::printfln("before test, id_dest={}, src={}", *id_dest, *id_src);
+    // rlib::printfln("debug: before test, id_dest={}, src={}", *id_dest, *id_src);
     sign_extend_if_required(*id_dest, *id_src);
-    rlib::printfln("after test, id_dest={}, src={}", *id_dest, *id_src);
+    // rlib::printfln("debug: after test, id_dest={}, src={}", *id_dest, *id_src);
   
     rtl_and(&id_dest->val, &id_dest->val, &id_src->val);
     operand_write(id_dest, &id_dest->val);
@@ -50,28 +47,49 @@ namespace EHelperImpl {
   }
   
   make_EHelper(or_) {
-    TODO();
+    sign_extend_if_required(*id_dest, *id_src);
+  
+    rtl_or(&id_dest->val, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &id_dest->val);
+  
+    rtl_update_ZFSF(&id_dest->val, id_dest->width);
+    cpu_eflags::get<cpu_eflags::CF>() = cpu_eflags::get<cpu_eflags::OF>() = false;
   
     print_asm_template2(or);
   }
   
   make_EHelper(sar) {
-    TODO();
-    // unnecessary to update CF and OF in NEMU
+    // r: dbt
+    // warning: unnecessary to update CF and OF in NEMU
+    if (id_dest->width == 1) {
+    	id_dest->val = (int8_t)id_dest->val;
+    }
+    else if (id_dest->width == 2) {
+    	id_dest->val = (int16_t)id_dest->val;
+    }
+    rtl_sar(&t2, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &t2);
+    rtl_update_ZFSF(&t2, id_dest->width);
   
     print_asm_template2(sar);
   }
   
   make_EHelper(shl) {
-    TODO();
+    // r: dbt
     // unnecessary to update CF and OF in NEMU
-  
+    rtl_shl(&t2, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &t2);
+    rtl_update_ZFSF(&t2, id_dest->width);  
+
     print_asm_template2(shl);
   }
   
   make_EHelper(shr) {
-    TODO();
+    // r: dbt
     // unnecessary to update CF and OF in NEMU
+    rtl_shr(&t2, &id_dest->val, &id_src->val);
+    operand_write(id_dest, &t2);
+    rtl_update_ZFSF(&t2, id_dest->width);
   
     print_asm_template2(shr);
   }
@@ -86,13 +104,31 @@ namespace EHelperImpl {
   }
   
   make_EHelper(not_) {
-    TODO();
+    rtl_not(&id_dest->val, &id_dest->val);
+    operand_write(id_dest, &id_dest->val);
   
     print_asm_template1(not);
   }
   
   make_EHelper(rol) {
-    TODO();
+    // r: dbt
+	  rtl_shl(&t0, &id_dest->val, &id_src->val);
+	  if (decoding.is_operand_size_16) {
+	  	t3 = 0;
+	  	rtl_addi(&t1, &t3, 16);
+	  	rtl_sub(&t1, &t1, &id_src->val);
+	  	rtl_shr(&t2, &id_dest->val, &t1);
+	  } else {
+	  	t3 = 0;
+	  	rtl_addi(&t1, &t3, 32);
+	  	rtl_sub(&t1, &t1, &id_src->val);
+	  	rtl_shr(&t2, &id_dest->val, &t1);
+	  }
+	  rtl_or(&t0, &t0, &t2);
+	  operand_write(id_dest, &t0);
+
+	  // unnecessary to update CF and OF in NEMU
+	  rtl_update_ZFSF(&t0, id_dest->width);
   
     print_asm_template1(rol);
   }
diff --git a/nexus-am/tests/cputest/tests/r.c b/nexus-am/tests/cputest/tests/r.c
deleted file mode 100644
index a2a1beada540b4b9df7a8a540561699b24185839..0000000000000000000000000000000000000000
--- a/nexus-am/tests/cputest/tests/r.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "trap.h"
-
-int min3(int x, int y, int z) {
-	int m;
-	if(x < y) { m = x; }
-	else { m = y; }
-	if(z < m) m = z;
-	return m;
-}
-
-//int test_data[] = {0, 0x7fffffff, 0x80000000, 0xffffffff};
-//int ans [] = {0, 0, -2147483648, -1, 0, 0, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1, 0, 0, -2147483648, -1, 0, 2147483647, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1, -1, -1, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1};
-
-int test_data[] = {1,2};
-int ans [] = {1,1,1,   1,1,1,   1,1,2};
-
-#define NR_DATA (sizeof(test_data) / sizeof(test_data[0]))
-
-int main() {
-    int rmax = 0;
-    if(test_data[0] < test_data[1])
-        rmax = test_data[1];
-    else
-        rmax = test_data[0];
-    nemu_assert(rmax == test_data[1]);
-    return 0;
-
-
-
-
-	int i, j, k, ans_idx = 0;
-    //nemu_assert(min3(4,6,8) == 4);
-
-	for(i = 0; i < NR_DATA; i ++) {
-		for(j = 0; j < NR_DATA; j ++) {
-			for(k = 0; k < NR_DATA; k ++) {
-				nemu_assert(min3(test_data[i], test_data[j], test_data[k]) == ans[ans_idx ++]);
-			}
-			//nemu_assert(k == NR_DATA);
-		}
-		//nemu_assert(j == NR_DATA);
-	}
-
-	//nemu_assert(i == NR_DATA);
-
-	return 0;
-}