implemented flag for comparison result
This commit is contained in:
parent
ba72dae68f
commit
cf5ed7b601
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -7,7 +7,7 @@
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/bin/tcpu",
|
||||
"windows": { "program": "${workspaceFolder}/bin/tcpu.exe" },
|
||||
"args": [ "-c", "../examples/conditional_jump.tasm", "o.bin", "--debug", "-i", "o.bin" ],
|
||||
"args": [ "-c", "../examples/loop.tasm", "o.bin", "--debug", "-i", "o.bin" ],
|
||||
"cwd": "${workspaceFolder}/bin",
|
||||
"preLaunchTask": "build_exec_dbg",
|
||||
"stopAtEntry": false,
|
||||
|
||||
@ -43,7 +43,7 @@ Machine code interpreter written in pure C. Can execute programs up to 1 MEGABYT
|
||||
| EXIT | | stop the program with exit code in `eax` |
|
||||
| SYS | | call system function |
|
||||
| |
|
||||
| MOVC | `dst_register`, `value` | push constant value into `dst_register` |
|
||||
| MOVC | `dst_register`, `const_value` | push constant value into `dst_register` |
|
||||
| MOVR | `dst_register`, `src_register` | copy value from `src_register` to `dst_register` |
|
||||
| |
|
||||
| ADD | `dst_register`, `src_register` | `dst += src` |
|
||||
@ -65,9 +65,9 @@ Machine code interpreter written in pure C. Can execute programs up to 1 MEGABYT
|
||||
| XOR | `dst_register`, `src_register` | `dst = dst ^ src` |
|
||||
| AND | `dst_register`, `src_register` | `dst = dst & src` |
|
||||
| |
|
||||
| JMP | `dst_register` | goto `dst` |
|
||||
| JNZ | `dst_register` | if (`cmp_flag` != 0) goto `dst` |
|
||||
| JZ | `dst_register` | if (`cmp_flag` == 0) goto `dst` |
|
||||
| JMP | `dst_address_const` | goto `dst` |
|
||||
| JNZ | `dst_address_const` | if (`cmp_flag` != 0) goto `dst` |
|
||||
| JZ | `dst_address_const` | if (`cmp_flag` == 0) goto `dst` |
|
||||
|
||||
### System functions
|
||||
To call a system function you need to push values to registers and write `SYS` opcode. The return value of a function will will be avaliable in `ax` after call.
|
||||
|
||||
@ -5,9 +5,9 @@ Example of behavior change depending on some condition
|
||||
.main:
|
||||
movc ax 1
|
||||
movc bx 2
|
||||
gt cx ax bx
|
||||
jnz @true cx
|
||||
jz @false cx
|
||||
gt ax bx
|
||||
jnz @true
|
||||
jz @false
|
||||
|
||||
.true:
|
||||
const8 true.msg "true\n"
|
||||
|
||||
@ -3,6 +3,7 @@ Example of self-repeating code section
|
||||
*/
|
||||
|
||||
.main:
|
||||
movc dx 0; // loop counter
|
||||
|
||||
.loop
|
||||
const8 datum "ITERATION!!! "
|
||||
@ -11,4 +12,11 @@ movc ah 1
|
||||
movc rbx @datum
|
||||
movc ecx #datum
|
||||
sys
|
||||
jmp @loop
|
||||
|
||||
movc cx 1
|
||||
add dx cx
|
||||
movc cx 8
|
||||
lt dx cx
|
||||
jnz @loop
|
||||
movc rax 0
|
||||
exit
|
||||
|
||||
@ -30,6 +30,10 @@ typedef struct VM {
|
||||
};
|
||||
Register array[4];
|
||||
} registers;
|
||||
|
||||
struct {
|
||||
bool cmp; // result of comparison operation
|
||||
} flags;
|
||||
|
||||
VMState state;
|
||||
char* NULLABLE(error_message); // not null on if state == VMState_InternalError
|
||||
|
||||
@ -11,40 +11,26 @@ i32 JMP_impl(VM* vm){
|
||||
}
|
||||
|
||||
|
||||
// JNZ [destination address] [condition register]
|
||||
// JNZ [destination address]
|
||||
i32 JNZ_impl(VM* vm){
|
||||
u64 dst_addr = 0;
|
||||
readVar(dst_addr);
|
||||
|
||||
RegisterCode reg_code = 0;
|
||||
readRegisterCode(reg_code);
|
||||
u64 cond_reg_value = 0;
|
||||
VM_registerRead(vm, &cond_reg_value, reg_code);
|
||||
|
||||
if(cond_reg_value != 0){
|
||||
if(vm->flags.cmp != 0){
|
||||
vm->current_pos = dst_addr;
|
||||
}
|
||||
|
||||
return sizeof(dst_addr) + sizeof(reg_code);
|
||||
return sizeof(dst_addr);
|
||||
}
|
||||
|
||||
// JZ [destination address] [condition register]
|
||||
// JZ [destination address]
|
||||
i32 JZ_impl(VM* vm){
|
||||
u64 dst_addr = 0;
|
||||
{
|
||||
if(!VM_dataRead(vm, &dst_addr, vm->current_pos, sizeof(dst_addr)))
|
||||
return -1;
|
||||
vm->current_pos += sizeof(dst_addr);
|
||||
};
|
||||
readVar(dst_addr);
|
||||
|
||||
RegisterCode reg_code = 0;
|
||||
readRegisterCode(reg_code);
|
||||
u64 cond_reg_value = 0;
|
||||
VM_registerRead(vm, &cond_reg_value, reg_code);
|
||||
|
||||
if(cond_reg_value == 0){
|
||||
if(vm->flags.cmp == 0){
|
||||
vm->current_pos = dst_addr;
|
||||
}
|
||||
|
||||
return sizeof(dst_addr) + sizeof(reg_code);
|
||||
return sizeof(dst_addr);
|
||||
}
|
||||
|
||||
@ -45,18 +45,15 @@ i32 NAME##_impl (VM* vm) {\
|
||||
return sizeof(dst_reg_code) + sizeof(src_reg_code);\
|
||||
}
|
||||
|
||||
#define OPERATOR_IMPL_3(NAME, OPERATOR)\
|
||||
#define OPERATOR_IMPL_CMP_FLAG(NAME, OPERATOR)\
|
||||
i32 NAME##_impl (VM* vm) {\
|
||||
RegisterCode dst_reg_code = 0, src0_reg_code = 0, src1_reg_code = 0;\
|
||||
readRegisterCode(dst_reg_code);\
|
||||
RegisterCode src0_reg_code = 0, src1_reg_code = 0;\
|
||||
readRegisterCode(src0_reg_code);\
|
||||
readRegisterCode(src1_reg_code);\
|
||||
u64 dst_reg_value = 0, src0_reg_value = 0, src1_reg_value = 0;\
|
||||
VM_registerRead(vm, &dst_reg_value, dst_reg_code);\
|
||||
u64 src0_reg_value = 0, src1_reg_value = 0;\
|
||||
VM_registerRead(vm, &src0_reg_value, src0_reg_code);\
|
||||
VM_registerRead(vm, &src1_reg_value, src1_reg_code);\
|
||||
\
|
||||
dst_reg_value = src0_reg_value OPERATOR src1_reg_value;\
|
||||
VM_registerWrite(vm, &dst_reg_value, dst_reg_code);\
|
||||
return sizeof(dst_reg_code) + sizeof(src0_reg_code) + sizeof(src1_reg_code);\
|
||||
vm->flags.cmp = src0_reg_value OPERATOR src1_reg_value;\
|
||||
return sizeof(src0_reg_code) + sizeof(src1_reg_code);\
|
||||
}
|
||||
|
||||
@ -17,20 +17,20 @@ OPERATOR_IMPL_2(XOR, ^)
|
||||
OPERATOR_IMPL_2(AND, &)
|
||||
|
||||
|
||||
/// EQ [dst_register] [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_3(EQ, ==)
|
||||
/// EQ [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_CMP_FLAG(EQ, ==)
|
||||
|
||||
/// NE [dst_register] [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_3(NE, !=)
|
||||
/// NE [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_CMP_FLAG(NE, !=)
|
||||
|
||||
/// LT [dst_register] [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_3(LT, <)
|
||||
/// LT [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_CMP_FLAG(LT, <)
|
||||
|
||||
/// LE [dst_register] [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_3(LE, <=)
|
||||
/// LE [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_CMP_FLAG(LE, <=)
|
||||
|
||||
/// GT [dst_register] [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_3(GT, >)
|
||||
/// GT [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_CMP_FLAG(GT, >)
|
||||
|
||||
/// GE [dst_register] [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_3(GE, >=)
|
||||
/// GE [src0_register] [src1_register]
|
||||
OPERATOR_IMPL_CMP_FLAG(GE, >=)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user