模拟8086cpu-寻址方式的实现(全)

7种寻址方式可识别的写法
立即数寻址 mov ax 2000
寄存器寻址 mov ax bx
寄存器间接寻址 mov ax [bx]
直接寻址 mov ax [2000]
相对基址寻址 mov ax [bx/bp/si/di+2000]
基址变址寻址 mov ax [bx/bp+si/di]
相对基址变址寻址 mov ax [bx/bp+si/di+2000]

int get_value(char* operand){
	int address;
    int value;// 返回这个值
	int a,b,c;// 作为中间量计算时候用
    // 过程代码
    return value;
}

后面五种带[]于是先进行if(operand[0] == '[')判断。

这部分还是会用到字符串分割的内容,所以用c写了。

格式化读取字符串

%[^+]:读取第一个字符串,直到遇到加号。
char base_str[8],offset_str[8],val_str[8];
int part_count = sscanf(operand,"[%[^+]+%[^+]+%[^]]]",base_str,offset_str,val_str);

会有如下测试结果

char test0[]="[BX+SI+100]";
>>>BX SI 100
char test1[]="[BX+SI]";
>>>BX SI]
char test2[]="[BX+100]";
>>>BX 100]
char test3[]="[100]";
>>>100]
char test4[]="[BX]";
>>>BX]

啊难道你这样不是bug吗?

我可以解释,这样的话我条件判断一下带结束括号的就不用判断用户有没有认真输全两个括号了。(并不是好办法。。。我只是不会写。)

相对基址变址寻址 mov ax [bx/bp+si/di+2000]

if(part_count==3){/*相对基址变址*/
    if(strcmp(base_str,"BX")==0){a = cpu->registers[BX];}
    else if(strcmp(base_str,"BP")==0){a = cpu->registers[BP];}
    if(strcmp(offset_str,"SI")==0){b = cpu->registers[BX];}
    else if(strcmp(offset_str,"DI")==0){b = cpu->registers[BP];}
    c = atoi(val_str);
    address = a + b + c;
}

基址变址寻址 mov ax [bx/bp+si/di]

相对基址寻址 mov ax [bx/bp/si/di+2000]

这两种因为就把字符串分成两份就放一起写了。

else if(part_count==2){
    // 基址变址寻址
    if(strcmp(base_str,"BX")==0){printf("bx");/*a = cpu->registers[BX];*/}
    else if(strcmp(base_str,"BP")==0){printf("bp");/*a = cpu->registers[BP];*/}
    else if(strcmp(base_str,"SI")==0){printf("si");/*a = cpu->registers[BP];*/}
    else if(strcmp(base_str,"DI")==0){printf("di");/*a = cpu->registers[BP];*/}

    if(strcmp(offset_str,"SI]")==0){printf("si");/*a = cpu->registers[BX];*/}
    else if(strcmp(offset_str,"DI]")==0){printf("di");/*a = cpu->registers[BP];*/}
    // 相对寄至寻址
    else{b = atoi(offset_str);}
}

寄存器间接寻址 mov ax [bx]

直接寻址 mov ax [2000]

else if(part_count==1){
    // 寄存器间接寻址
    if(!strcmp(base_str,"BX]")){address = cpu->registers[BX];}
    else if(!strcmp(base_str,"SI]")){address = cpu->registers[SI];}
    else if(!strcmp(base_str,"DI]")){address = cpu->registers[DI];}
    else if(!strcmp(base_str,"SP]")){address = cpu->registers[SP];}
    else if(!strcmp(base_str,"BP]")){address = cpu->registers[BP];}
    // 直接寻址
    else{address = atoi(base_str);}
}

再去访问address对应的内存就好了

value = cpu->memory[address];

剩下不带括号的两种

立即数寻址 mov ax 2000

寄存器寻址 mov ax bx

//寄存器寻址
if(!strcmp(base_str,"AX")){value = cpu->registers[AX];}
else if(!strcmp(base_str,"BX")){value = cpu->registers[BX];}
else if(!strcmp(base_str,"CX")){value = cpu->registers[CX];}
else if(!strcmp(base_str,"DX")){value = cpu->registers[DX];}
else if(!strcmp(base_str,"SI")){value = cpu->registers[SI];}
else if(!strcmp(base_str,"DI")){value = cpu->registers[DI];}
else if(!strcmp(base_str,"SP")){value = cpu->registers[SP];}
else if(!strcmp(base_str,"BP")){value = cpu->registers[BP];}
//立即数寻址
else{value = atoi(base_str);}

总的代码,可以运行辣,能想到的小问题我改好了也。

typedef struct{
	unsigned int ip;//指令指针 
	string memory[MEMORY_SIZE];
	int registers[8];
	bool status_flags[6];
	int data_bus;
	bool control_bus_read;
	bool control_bus_write;
}simple8086;
void Init_simple8086(simple8086* cpu) {
    cpu->ip = 0;
    memset(cpu->registers, 0, sizeof(cpu->registers));
    cpu->data_bus = 0;
    cpu->control_bus_read = false;
    cpu->control_bus_write = false;
}
int get_value(char* operand,simple8086* cpu){
	int address,value;
	int a,b,c;	
	char base_str[8],offset_str[8], val_str[8];
	if(operand[0] == '['){
		int part_count = sscanf(operand,"[%[^+]+%[^+]+%[^]]]",base_str,offset_str,val_str);
		printf("%s %s %s\n",base_str,offset_str,val_str);
		
		if(part_count==3){
			if(strcmp(base_str,"BX")==0){a = cpu->registers[BX];}
		    else if(strcmp(base_str,"BP")==0){a = cpu->registers[BP];}
		    
		    if(strcmp(offset_str,"SI")==0){b = cpu->registers[SI];}
		    else if(strcmp(offset_str,"DI")==0){b = cpu->registers[DI];}
		    c = atoi(val_str);
		    address = a + b + c;
		}else if(part_count==2){
			// 基址变址寻址
		    if(strcmp(base_str,"BX")==0){printf("bx");a = cpu->registers[BX];}
		    else if(strcmp(base_str,"BP")==0){printf("bp");a = cpu->registers[BP];}
		    else if(strcmp(base_str,"SI")==0){printf("si");a = cpu->registers[SI];}
		    else if(strcmp(base_str,"DI")==0){printf("di");a = cpu->registers[DI];}
		
		    if(strcmp(offset_str,"SI]")==0){printf("si");a = cpu->registers[SI];}
		    else if(strcmp(offset_str,"DI]")==0){printf("di");a = cpu->registers[DI];}
		    // 相对基址寻址
		    else{b = atoi(offset_str);}
		    address = a + b;
		}else if(part_count==1){
		 // 寄存器间接寻址
		    if(!strcmp(base_str,"BX]")){address = cpu->registers[BX];}
		    else if(!strcmp(base_str,"SI]")){address = cpu->registers[SI];}
		    else if(!strcmp(base_str,"DI]")){address = cpu->registers[DI];}
		    else if(!strcmp(base_str,"SP]")){address = cpu->registers[SP];}
		    else if(!strcmp(base_str,"BP]")){address = cpu->registers[BP];}
		    // 直接寻址
		    else{address = atoi(base_str);}
		}
		value = stoi(cpu->memory[address]);
	}else{
		if(!strcmp(operand,"AX")){value = cpu->registers[AX];}
		else if(!strcmp(operand,"BX")){value = cpu->registers[BX];}
		else if(!strcmp(operand,"CX")){value = cpu->registers[CX];}
		else if(!strcmp(operand,"DX")){value = cpu->registers[DX];}
		else if(!strcmp(operand,"SI")){value = cpu->registers[SI];}
		else if(!strcmp(operand,"DI")){value = cpu->registers[DI];}
		else if(!strcmp(operand,"SP")){value = cpu->registers[SP];}
		else if(!strcmp(operand,"BP")){value = cpu->registers[BP];}
		else{value = atoi(operand);}
	}
//	cout<<operand<<endl;
//	printf("%d\n",value); 
	return value;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值