diff --git a/nemu/src/cpu/decode/decode.cc b/nemu/src/cpu/decode/decode.cc
index 94c08abfe26486fe974ff618736ff234f133c232..620d6669ac3d1f32bad0b99becfa837b8df57425 100644
--- a/nemu/src/cpu/decode/decode.cc
+++ b/nemu/src/cpu/decode/decode.cc
@@ -286,7 +286,6 @@ namespace DHelperImpl {
   
   make_DHelper(J) {
     make_DopHelper_funcname(SI)(eip, id_dest, false);
-    rlib::println("debug: J decoder: id_dest=", *id_dest);
     rtl_sext(&id_dest->imm, &id_dest->imm, id_dest->width);
     // the target address can be computed in the decode stage
     decoding.jmp_eip = id_dest->simm + *eip;
diff --git a/nemu/src/cpu/exec/arith.cc b/nemu/src/cpu/exec/arith.cc
index 8f6c9cbcc0bbb2670167ab3a90af5e589fd2e9a0..fb376f94bcffbcabe9d546e04c8c844c924af81c 100644
--- a/nemu/src/cpu/exec/arith.cc
+++ b/nemu/src/cpu/exec/arith.cc
@@ -8,10 +8,13 @@ namespace EHelperImpl {
   	rtl_sext(&t2, &id_src->val, id_src->width);
   
   	rtl_add(&t0, &t1, &t2);
-  	t3 = (t0 < t1);
-  	rtl_set_CF(&t3);
-  	t3 = ((((int32_t)(t1) >= 0) ^ (((int32_t)(t2) >= 0 ))) && (((int32_t)(t0) < 0) ^ (((int32_t)(t2) >= 0 )) ));
-  	rtl_set_OF(&t3);
+
+    cpu_eflags::get<cpu_eflags::CF>() = (t0 < t1);
+
+    bool operandsSameSign = not ((t1 xor t2) bitand 0x80000000);
+    bool resFlippedSign = ((t1 xor t0) bitand 0x80000000);
+    cpu_eflags::get<cpu_eflags::OF>() = resFlippedSign and operandsSameSign;
+
   	rtl_update_ZFSF(&t0, 4);
   	operand_write(id_dest, &t0);
   
@@ -23,10 +26,13 @@ namespace EHelperImpl {
   	rtl_sext(&t2, &id_src->val, id_src->width);
   
   	rtl_sub(&t0, &t1, &t2);
-  	t3 = (t0 > t1);
-  	rtl_set_CF(&t3);
-  	t3 = ((((int32_t)(t1) < 0) == (((int32_t)(t2) >> 31) == 0)) && (((int32_t)(t0) < 0) != ((int32_t)(t1) < 0)));
-  	rtl_set_OF(&t3);
+
+    cpu_eflags::get<cpu_eflags::CF>() = (t0 > t1);
+
+    bool operandsSameSign = not ((t1 xor t2) bitand 0x80000000);
+    bool resFlippedSign = ((t1 xor t0) bitand 0x80000000);
+    cpu_eflags::get<cpu_eflags::OF>() = resFlippedSign and not operandsSameSign;
+
   	rtl_update_ZFSF(&t0, 4);
   	operand_write(id_dest, &t0);
   
@@ -36,14 +42,18 @@ namespace EHelperImpl {
   
   
   make_EHelper(cmp) {
+    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);
   
   	rtl_sub(&t0, &t1, &t2);
-  	t3 = (t0 > t1);
-  	rtl_set_CF(&t3);
-  	t3 = ((((int32_t)(t1) < 0) == (((int32_t)(t2) >> 31) == 0)) && (((int32_t)(t0) < 0) != ((int32_t)(t1) < 0)));
-  	rtl_set_OF(&t3);
+
+    cpu_eflags::get<cpu_eflags::CF>() = (t0 > t1);
+
+    bool operandsSameSign = not ((t1 xor t2) bitand 0x80000000);
+    bool resFlippedSign = ((t1 xor t0) bitand 0x80000000);
+    cpu_eflags::get<cpu_eflags::OF>() = resFlippedSign and not operandsSameSign;
+
   	rtl_update_ZFSF(&t0, 4);
   
     print_asm_template2(cmp);
diff --git a/nemu/src/monitor/debug/ui.cc b/nemu/src/monitor/debug/ui.cc
index ddb92d2487a38a4eceac45c39817455f82f25941..086b21a1776a63c1d461a29738c2cc828a3f4c3a 100644
--- a/nemu/src/monitor/debug/ui.cc
+++ b/nemu/src/monitor/debug/ui.cc
@@ -174,7 +174,8 @@ static int cmd_info(char *_args) {
     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));
-    printfln("%eip={}", dumpReg(cpu.eip));
+    printfln("%eip={}, CF/OF/SF/ZF={}/{}/{}/{}", dumpReg(cpu.eip), cpu_eflags::get<cpu_eflags::CF>(), 
+            cpu_eflags::get<cpu_eflags::OF>(), cpu_eflags::get<cpu_eflags::SF>(), cpu_eflags::get<cpu_eflags::ZF>());
   }
   else if(string(_args).strip() == "w") {
     println("Watchpoints:");
diff --git a/nexus-am/tests/cputest/tests/r.c b/nexus-am/tests/cputest/tests/r.c
index ca756700f451a916b07f3f740e93a11657241c98..a2a1beada540b4b9df7a8a540561699b24185839 100644
--- a/nexus-am/tests/cputest/tests/r.c
+++ b/nexus-am/tests/cputest/tests/r.c
@@ -1,24 +1,47 @@
 #include "trap.h"
 
-int add(int a, int b) {
-	int c = a + b;
-	return c;
+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, 1, 2};
-int ans[] = {0, 1, 2,1,2,3,2,3,4};
+//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 i, j, ans_idx = 0;
+    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 ++) {
-        nemu_assert(1);
+			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(j == NR_DATA);
 	}
-	nemu_assert(i == NR_DATA);
+
+	//nemu_assert(i == NR_DATA);
 
 	return 0;
 }