Пример #1
0
/* 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; }
}
Пример #2
0
/* 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; }
}
Пример #3
0
/* 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; }
}
Пример #4
0
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; }
	}
}
Пример #5
0
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; }

}
Пример #7
0
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; }
}