/* Simulate how the CPU works. */ void cpu_exec(volatile uint32_t n) { if(nemu_state == END) { printf("Program execution has ended. To restart the program, exit NEMU and run again.\n"); return; } nemu_state = RUNNING; #ifdef DEBUG volatile uint32_t n_temp = n; #endif setjmp(jbuf); for(; n > 0; n --) { #ifdef DEBUG swaddr_t eip_temp = cpu.eip; if((n & 0xffff) == 0) { /* Output some dots while executing the program. */ fputc('.', stderr); } #endif /* Execute one instruction, including instruction fetch, * instruction decode, and the actual execution. */ int instr_len = exec(cpu.eip); cpu.eip += instr_len; #ifdef DEBUG print_bin_instr(eip_temp, instr_len); strcat(asm_buf, assembly); Log_write("%s\n", asm_buf); if(n_temp < MAX_INSTR_TO_PRINT) { printf("%s\n", asm_buf); } #endif /* TODO: check watchpoints here. */ WP *tail=getHead(); uint32_t result; bool f; while(tail){ result=expr(tail->expr,&f); if(f==false) return; if(result!=tail->result){ nemu_state=STOP; printf("监视点%d: %s\n",tail->NO,tail->expr); printf("原值 result=%d\n",tail->result); printf("新值 result=%d\n",result); tail->result=result; } tail=tail->next; } if(nemu_state != RUNNING) { return; } } if(nemu_state == RUNNING) { nemu_state = STOP; } }
/* Simulate how the CPU works. */ void cpu_exec(volatile uint32_t n) { if(nemu_state == END) { printf("Program execution has ended. To restart the program, exit NEMU and run again.\n"); return; } nemu_state = RUNNING; #ifdef DEBUG volatile uint32_t n_temp = n; #endif setjmp(jbuf); for(; n > 0; n --) { #ifdef DEBUG swaddr_t eip_temp = cpu.eip; if((n & 0xffff) == 0) { /* Output some dots while executing the program. */ fputc('.', stderr); } #endif /* Execute one instruction, including instruction fetch, * instruction decode, and the actual execution. */ int instr_len = exec(cpu.eip); // if (cpu.eip>=0xc0100740 && cpu.eip <=0xc0100744) printf("%08x %d\n", cpu.eip, instr_len); cpu.eip += instr_len; // if (cpu.eip>=0xc0100740 && cpu.eip <=0xc0100744) printf("%08x %d\n", cpu.eip, instr_len); #ifdef DEBUG print_bin_instr(eip_temp, instr_len); strcat(asm_buf, assembly); Log_write("%s\n", asm_buf); if(n_temp < MAX_INSTR_TO_PRINT) { printf("%s\n", asm_buf); } #endif /* TODO: check watchpoints here. */ if (check()) { nemu_state=STOP; } if(nemu_state != RUNNING) { return; } if(cpu.INTR & eflags.IF) { uint32_t intr_no = i8259_query_intr(); i8259_ack_intr(); int len; len = get_len(); cpu.eip--; raise_intr(intr_no, len); } } if(nemu_state == RUNNING) { nemu_state = STOP; } }
/* Simulate how the CPU works. */ void cpu_exec(volatile uint32_t n) { if(nemu_state == END) { printf("Program execution has ended. To restart the program, exit NEMU and run again.\n"); return; } nemu_state = RUNNING; #ifdef DEBUG volatile uint32_t n_temp = n; #endif setjmp(jbuf); for(; n > 0; n --) { #ifdef DEBUG swaddr_t eip_temp = cpu.eip; if((n & 0xffff) == 0) { /* Output some dots while executing the program. */ fputc('.', stderr); } #endif /* Execute one instruction, including instruction fetch, * instruction decode, and the actual execution. */ int instr_len = exec(cpu.eip); cpu.eip += instr_len; #ifdef DEBUG print_bin_instr(eip_temp, instr_len); strcat(asm_buf, assembly); Log_write("%s\n", asm_buf); if(n_temp < MAX_INSTR_TO_PRINT) { printf("%s\n", asm_buf); } #endif if (check_change()) { show_watchpoint(); break; } if(nemu_state != RUNNING) { return; } } if(nemu_state == RUNNING) { nemu_state = STOP; } }
void cpu_exec(volatile uint32_t n) { volatile uint32_t n_temp = n; setjmp(jbuf); for(; n > 0; n --) { swaddr_t eip_temp = cpu.eip; BP* current; /*如果触发断点成功且eip-1恰好是int3指令*/ if(isBreak == true && swaddr_read(cpu.eip-1,1) == INT3_CODE) { cpu.eip--; current = ret_head();//返回组织使用中断点的head指针 while(current -> addr != cpu.eip)//找存放相应内存地址的断点结构 current = current -> next; swaddr_write(cpu.eip,1,current -> sav_istr);//临时恢复原来的指令 eip_temp--; } int instr_len = exec(cpu.eip); /*刚执行完恢复的指令要马上设置回断点,使其能反复触发*/ if(isBreak == true && swaddr_read(eip_temp,1) != INT3_CODE)//刚触发断点但断点的位置刚被恢复为原指令 { swaddr_write(eip_temp,1,INT3_CODE); isBreak = false;//告别刚刚触发的那个断点,初始化isBreak,否则执行下一条正常指令也会进入这个判断 } if(!isChange()) isBreak = true; cpu.eip += instr_len; if(n_temp != -1 || (enable_debug && !quiet)) { print_bin_instr(eip_temp, instr_len); puts(assembly); } if(nemu_state == INT) { printf("\n\nUser interrupt\n"); return; } else if(isBreak == true) { return; }//如果因触发断点而停止,回到主循环等待下一条指令 else if(nemu_state == END) { return; } } }
void cpu_exec(volatile uint32_t n) { volatile uint32_t n_temp = n; setjmp(jbuf); for(; n > 0; n --) { swaddr_t eip_temp = cpu.eip; int f = 0; int instr_len = exec(cpu.eip); cpu.eip += instr_len; if(f) { printf("cpu.eip %x\n", cpu.eip); f = 0; } if (n_temp != -1 || (enable_debug && !quiet)) { print_bin_instr(eip_temp, instr_len); puts(assembly); } int_polling(); switch(nemu_state) { case INT: printf("\n\nUser interrupt\n"); case END: return; case TEST_INT: printf("---Stop to confirm, press `c' to continue---\n"); return; } } }
/* Simulate how the CPU works. */ void cpu_exec(volatile uint32_t n) { if(nemu_state == END) { printf("Program execution has ended. To restart the program, exit NEMU and run again.\n"); return; } nemu_state = RUNNING; #ifdef DEBUG volatile uint32_t n_temp = n; #endif setjmp(jbuf); for(; n > 0; n --) { #ifdef DEBUG swaddr_t eip_temp = cpu.eip; if((n & 0xffff) == 0) { /* Output some dots while executing the program. */ fputc('.', stderr); } #endif /* Execute one instruction, including instruction fetch, * instruction decode, and the actual execution. */ int instr_len = exec(cpu.eip); cpu.eip += instr_len; #ifdef DEBUG print_bin_instr(eip_temp, instr_len); strcat(asm_buf, assembly); Log_write("%s\n", asm_buf); if(n_temp < MAX_INSTR_TO_PRINT) { printf("%s\n", asm_buf); } #endif /* TODO: check watchpoints here. */ WP *p; uint32_t index; bool success=true; p=gethead(); int flag=0; while(p!=NULL) { index=expr(p->expr,&success); if(success==false) printf("Meet a wrong expression!"); if(p->ans!=index) { flag=1; printf("watchpoint %d: %s\n",p->NO+1,p->expr); printf("Old value = %d\n",p->ans); printf("New value = %d\n",index); p->ans=index; } p=p->next; } if(flag==1) nemu_state=STOP; if(nemu_state != RUNNING) { return; } if(cpu.INTR & cpu.EFLAGS.IF) { uint32_t intr_no = i8259_query_intr(); i8259_ack_intr(); raise_intr(intr_no); } } if(nemu_state == RUNNING) { nemu_state = STOP; } }
void cpu_exec(volatile uint32_t n) { if(nemu_state == END) { printf("Program execution has ended. To restart the program, exit NEMU and run again.\n"); return; } nemu_state = RUNNING; #ifdef DEBUG volatile uint32_t n_temp = n; #endif setjmp(jbuf); for(; n > 0; n --) { #ifdef DEBUG swaddr_t eip_temp = cpu.eip; if((n & 0xffff) == 0) { /* Output some dots while executing the program. */ fputc('.', stderr); } #endif /* Execute one instruction, including instruction fetch, * instruction decode, and the actual execution. */ int instr_len = exec(cpu.eip); //printf("instr_len is %x in cpu-exec.c\n",instr_len); cpu.eip += instr_len; si_count++; #ifdef DEBUG #endif print_bin_instr(eip_temp, instr_len); strcat(asm_buf, assembly); Log_write("%s\n", asm_buf); if(n_temp < MAX_INSTR_TO_PRINT) { printf("%s\n", asm_buf); } /* TODO: check watchpoints here. */ if(check_watchpoints()){ n=1; nemu_state = STOP; } if(nemu_state != RUNNING) { printf("Cache cost = %llu, L1 miss rate = %f, L2 miss rate = %f\n",(unsigned long long)(L2_get_cache_cost()+L1_get_cache_cost()), (double)L1_cache_miss/(double)L1_cache_access,(double)L2_cache_miss/(double)L2_cache_access); printf("Instruction executed: %llu\n",(long long unsigned)si_count); return; } //printf("cpu.eip is %x in rear cpu-exec.c\n",cpu.eip); //PA 4.4 if(cpu.INTR & eflags.eflags.IF) { //printf("cpu.INTR triggered\n"); uint32_t intr_no = i8259_query_intr(); i8259_ack_intr(); int len = get_instr_len(); cpu.eip --; //TODO: ?! raise_intr(intr_no, len); } } if(nemu_state == RUNNING) { nemu_state = STOP; } }