implemented flag for comparison result

This commit is contained in:
Timerix 2025-04-18 03:03:20 +05:00
parent ba72dae68f
commit cf5ed7b601
8 changed files with 45 additions and 50 deletions

2
.vscode/launch.json vendored
View File

@ -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,

View File

@ -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.

View File

@ -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"

View File

@ -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

View File

@ -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

View File

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

View File

@ -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);\
}

View File

@ -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, >=)