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;
}