mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
stuff
This commit is contained in:
parent
1dcad85a9c
commit
4f527e21aa
6
Makefile
6
Makefile
@ -16,6 +16,12 @@ DOSK = $(shell find ka -name '*.k')
|
||||
vm/a.out: $(DOSK)
|
||||
@cd ka && ../as/k-as.py dos.k 0x100000 ../vm/a.out
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
@cd vm && make clean
|
||||
@rm -f vm/a.out vm/k.exe vm/stdout.txt as/instrs.lst
|
||||
|
||||
test: kas vm/a.out
|
||||
@vm/k.exe vm/a.out > vm/stdout.txt
|
||||
@rm -f vm/a.out
|
||||
|
@ -203,7 +203,7 @@ def parse():
|
||||
def parse_preproc(line):
|
||||
global pdata
|
||||
|
||||
tok = line.split(' ', 2)
|
||||
tok = line.split(None, 2)
|
||||
|
||||
# preprocessor
|
||||
if len(tok) > 1 and tok[1] == ':=':
|
||||
|
23
ka/dos.k
23
ka/dos.k
@ -16,10 +16,29 @@ _start:
|
||||
jmp .1
|
||||
|
||||
;
|
||||
; Essential definitions
|
||||
; Some definitions
|
||||
;
|
||||
|
||||
CHAR_MIN := 0x80
|
||||
SHRT_MIN := 0x8000
|
||||
INT_MIN := 0x80000000
|
||||
LONG_MIN := 0x8000000000000000
|
||||
|
||||
XCHAR_MIN := 0xFFFFFFFFFFFFFF80
|
||||
XSHRT_MIN := 0xFFFFFFFFFFFF8000
|
||||
XINT_MIN := 0xFFFFFFFF80000000
|
||||
|
||||
CHAR_MAX := 0x7F
|
||||
INT_MAX := 0x7FFF
|
||||
SHRT_MAX := 0x7FFF
|
||||
INT_MAX := 0x7FFFFFFF
|
||||
LONG_MAX := 0x7FFFFFFFFFFFFFFF
|
||||
|
||||
BYTE_MAX := 0xFF
|
||||
WORD_MAX := 0xFFFF
|
||||
LWORD_MAX := 0xFFFFFFFF
|
||||
QWORD_MAX := 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
STRLEN_MAX := 0xFFFFFFFF
|
||||
|
||||
;
|
||||
; Include librairies
|
||||
|
@ -30,14 +30,10 @@ _itoa:
|
||||
cmp ax2, 10 ; base 10
|
||||
jmp.nz .conv
|
||||
|
||||
cmp ax1, -9223372036854775808 ; LONG_MIN
|
||||
jmp.z .min
|
||||
|
||||
sgn rdx, ax1 ; extract ax1 sign
|
||||
|
||||
cmp rdx, -1 ; negative?
|
||||
not.z ax1 ; -x = ~x+1
|
||||
inc.z ax1 ; need "neg" inst...
|
||||
neg.z ax1
|
||||
|
||||
; main loop
|
||||
.conv:
|
||||
@ -50,7 +46,7 @@ _itoa:
|
||||
cmp rsx, 9 ; rsx > 9 ?
|
||||
jmp.a .nondec
|
||||
|
||||
add rsx, 48 ; '0'
|
||||
add rsx, 48 ; '0'
|
||||
jmp .next
|
||||
|
||||
.nondec:
|
||||
@ -90,13 +86,6 @@ _itoa:
|
||||
mov b[ax0+1], 0
|
||||
ret
|
||||
|
||||
.min:
|
||||
mov ax1, .min10
|
||||
call strcpy
|
||||
ret
|
||||
|
||||
.min10 = "-9223372036854775808"
|
||||
|
||||
;
|
||||
; wrappers
|
||||
;
|
||||
|
51
ka/main.k
51
ka/main.k
@ -5,6 +5,10 @@
|
||||
; Main function
|
||||
;
|
||||
main:
|
||||
call itoa_test
|
||||
ret
|
||||
|
||||
stosb_test:
|
||||
cld
|
||||
mov rcx, 11
|
||||
mov rax, 33
|
||||
@ -44,7 +48,7 @@ movzx_test:
|
||||
|
||||
itoa_test:
|
||||
mov ax0, .buf
|
||||
mov ax1, -9223372036854775807
|
||||
mov ax1, LONG_MIN
|
||||
mov ax2, 10
|
||||
call itoa
|
||||
|
||||
@ -60,10 +64,6 @@ itoa_test:
|
||||
mov ax0, rax
|
||||
call print
|
||||
|
||||
mov rsi, 0x10
|
||||
mov rdi, 8
|
||||
lea rbi, b[rdi + rsi * 2 + 1]
|
||||
|
||||
ret
|
||||
|
||||
.buf = [32]
|
||||
@ -84,42 +84,55 @@ devtest:
|
||||
|
||||
.buf = [32]
|
||||
|
||||
strtest:
|
||||
enter
|
||||
|
||||
str_test:
|
||||
mov ax0, .msg
|
||||
call print
|
||||
|
||||
mov ax0, .buf
|
||||
mov ax0, .buf1
|
||||
mov ax1, .msg
|
||||
mov ax2, 5
|
||||
call strcpy
|
||||
|
||||
prn 10
|
||||
mov ax0, .buf1
|
||||
call print
|
||||
|
||||
mov ax0, .buf2
|
||||
mov ax1, .msg
|
||||
mov ax2, 8
|
||||
call strnzcpy
|
||||
|
||||
prn 10
|
||||
mov ax0, .buf
|
||||
mov ax1, 10
|
||||
mov ax0, .buf2
|
||||
mov ax1, 12
|
||||
call print_n
|
||||
|
||||
mov ax0, .buf
|
||||
mov ax0, .msg
|
||||
mov ax1, .buf1
|
||||
call strcmp
|
||||
mov rbx, rax
|
||||
|
||||
mov ax0, .buf2
|
||||
mov ax1, .msg
|
||||
call strcmp
|
||||
mov rsx, rax
|
||||
|
||||
mov ax0, .msg
|
||||
call strlen
|
||||
|
||||
leave
|
||||
ret
|
||||
|
||||
.msg = "HelloWorld :)"
|
||||
.buf = [32]
|
||||
.msg = "Hello World :)"
|
||||
|
||||
.buf1 = [32]
|
||||
.buf2 = "!!!!!!!!!!!!!"
|
||||
|
||||
;
|
||||
; Exit function
|
||||
;
|
||||
exit:
|
||||
enter
|
||||
|
||||
mov ax0, .msg
|
||||
call print
|
||||
|
||||
leave
|
||||
ret
|
||||
|
||||
.msg = "Goodbye World :(\n"
|
||||
|
@ -9,44 +9,24 @@
|
||||
; 1 if the first character that does not match has a greater value in str1 than in str2
|
||||
; -1 if the first character that does not match has a lower value in str1 than in str2
|
||||
;
|
||||
|
||||
strcmp:
|
||||
cmp b[ax0], b[ax1]
|
||||
jmp.nz .1
|
||||
|
||||
test b[ax0], b[ax0]
|
||||
jmp.z .1
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
jmp strcmp
|
||||
|
||||
.1:
|
||||
mov rax, b[ax0]
|
||||
sub rax, b[ax1]
|
||||
sgn rax, rax
|
||||
ret
|
||||
mov ax2, STRLEN_MAX
|
||||
jmp strncmp
|
||||
|
||||
;
|
||||
; int strncmp(const char *str1, const char *str2, int maxn)
|
||||
;
|
||||
strncmp:
|
||||
mov rcx, ax2
|
||||
mov.cxz rax, 0
|
||||
ret.cxz
|
||||
|
||||
.0:
|
||||
cmp b[ax0], b[ax1]
|
||||
jmp.nz .1
|
||||
cld
|
||||
rep.e cmpzsb ax0, ax1
|
||||
|
||||
test b[ax0], b[ax0]
|
||||
jmp.z .1
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
loop .0
|
||||
|
||||
.1:
|
||||
mov rax, b[ax0]
|
||||
sub rax, b[ax1]
|
||||
sgn rax, rax
|
||||
|
||||
ret
|
||||
|
||||
|
@ -5,34 +5,19 @@
|
||||
; void strcpy(char *, const char *)
|
||||
;
|
||||
strcpy:
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
test b[ax1], b[ax1]
|
||||
ret.z
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
jmp strcpy
|
||||
mov ax2, STRLEN_MAX
|
||||
jmp strncpy
|
||||
|
||||
;
|
||||
; void strncpy(char *, const char *, int)
|
||||
;
|
||||
strncpy:
|
||||
mov rcx, ax2
|
||||
j.cxz .2
|
||||
dec rcx
|
||||
ret.cxz
|
||||
|
||||
.1:
|
||||
mov b[ax0], b[ax1]
|
||||
cld
|
||||
rep.nz movsb ax0, ax1
|
||||
|
||||
test b[ax1], b[ax1]
|
||||
ret.z
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
loop .1
|
||||
|
||||
.2:
|
||||
ret
|
||||
|
||||
;
|
||||
@ -40,20 +25,15 @@ strncpy:
|
||||
;
|
||||
strnzcpy:
|
||||
mov rcx, ax2
|
||||
j.cxz .2
|
||||
ret.cxz
|
||||
|
||||
dec rcx
|
||||
jmp.cxz .1
|
||||
|
||||
cld
|
||||
rep.nz movsb ax0, ax1
|
||||
|
||||
.1:
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
test b[ax1], b[ax1]
|
||||
ret.z
|
||||
|
||||
inc ax0
|
||||
inc ax1
|
||||
loop .1
|
||||
|
||||
.2:
|
||||
mov b[ax0], 0
|
||||
ret
|
||||
|
||||
|
@ -1,37 +1,22 @@
|
||||
; The OS/K Team licenses this file to you under the MIT license.
|
||||
; See the LICENSE file in the project root for more information.
|
||||
|
||||
;
|
||||
; int strlen(char *)
|
||||
;
|
||||
strlen:
|
||||
xor rax, rax
|
||||
|
||||
.1:
|
||||
test b[ax0], b[ax0]
|
||||
ret.z
|
||||
|
||||
inc rax
|
||||
inc ax0
|
||||
jmp .1
|
||||
|
||||
;
|
||||
; int strnlen(char *, int)
|
||||
;
|
||||
strnlen:
|
||||
xor rax, rax
|
||||
|
||||
cld
|
||||
mov rcx, ax1
|
||||
j.cxz .2
|
||||
dec rcx
|
||||
rep.nz scasb ax0, 0
|
||||
|
||||
.1:
|
||||
test b[ax0], b[ax0]
|
||||
ret.z
|
||||
|
||||
inc rax
|
||||
inc ax0
|
||||
loop .1
|
||||
|
||||
.2:
|
||||
mov rax, ax1
|
||||
sub rax, rcx
|
||||
ret
|
||||
|
||||
;
|
||||
; int strlen(char *)
|
||||
;
|
||||
strlen:
|
||||
mov ax1, STRLEN_MAX
|
||||
jmp strnlen
|
||||
|
||||
|
19
vm/in/INSTRS
19
vm/in/INSTRS
@ -408,6 +408,9 @@ stosb r rim
|
||||
# %str = %str - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# Preserves CF, OF and SF
|
||||
# Sets ZF according to the loaded value
|
||||
#
|
||||
# When no parameters are given, %dest = RAX and %str = RSI
|
||||
# When one parameter is given, %dest = $1 and %str = RSI
|
||||
# When two parameters are given, %dest = $1 and %str = $2
|
||||
@ -460,6 +463,19 @@ cmpsb
|
||||
cmpsb r
|
||||
cmpsb r r
|
||||
|
||||
#
|
||||
# Safe compare bytes in strings (CMPZSx)
|
||||
#
|
||||
# Behaves precisely like CMPSx, except in the following case:
|
||||
# - If both [%str1] and [%str2] are zero, clears ZF (indicating NOT EQUAL)
|
||||
#
|
||||
# This prevents 'rep.e cmpsb' from looping infinitely when both strings
|
||||
# have the exact same content; this allows for short strcmp's
|
||||
#
|
||||
cmpzsb
|
||||
cmpzsb r
|
||||
cmpzsb r r
|
||||
|
||||
#
|
||||
# Move value from string to string (MOVSx)
|
||||
#
|
||||
@ -472,6 +488,9 @@ cmpsb r r
|
||||
# %str2 = %str2 - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
# Preserves CF, OF and SF
|
||||
# Sets ZF according to the moved value
|
||||
#
|
||||
# When no parameters are given, %str1 = RDI and %str2 = RSI
|
||||
# When one parameter is given, %str1 = RDI and %str2 = $1
|
||||
# When two parameters are given, %str1 = $1 and %str2 = $2
|
||||
|
@ -7,7 +7,8 @@
|
||||
|
||||
IMPL_START_2(sgn)
|
||||
{
|
||||
v1 = (long)v2 < 0 ? (ulong)-1L : 1;
|
||||
v1 = (v2 == 0 ? 0 :
|
||||
((long)v2 < 0 ? (ulong)-1L : 1));
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
|
201
vm/in/string.c
201
vm/in/string.c
@ -85,6 +85,10 @@ void lods_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
}
|
||||
|
||||
R(reg1) = readmem(ctx, R(reg2), len);
|
||||
|
||||
flg = (R(reg1) == 0 ? flg|ZF : flg&~ZF);
|
||||
|
||||
STR_MOVE(reg2, len);
|
||||
}
|
||||
|
||||
IMPL_START_0(lodsb)
|
||||
@ -113,22 +117,219 @@ IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
{
|
||||
ulong reg, val;
|
||||
|
||||
if (p2) {
|
||||
DECV(v2, p2);
|
||||
reg = p1->reg;
|
||||
val = v2;
|
||||
}
|
||||
|
||||
else if (p1) {
|
||||
DECV(v1, p1);
|
||||
reg = RDI;
|
||||
val = v1;
|
||||
}
|
||||
|
||||
else {
|
||||
reg = RDI;
|
||||
val = rax;
|
||||
}
|
||||
|
||||
ulong x = readmem(ctx, R(reg), len);
|
||||
COMPARE(x, val);
|
||||
|
||||
STR_MOVE(reg, len);
|
||||
}
|
||||
|
||||
IMPL_START_0(scasb)
|
||||
{
|
||||
scas_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(scasw)
|
||||
{
|
||||
scas_impl(ctx, p1, p2, 2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(scasl)
|
||||
{
|
||||
scas_impl(ctx, p1, p2, 4);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(scasq)
|
||||
{
|
||||
scas_impl(ctx, p1, p2, 8);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void cmps_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
{
|
||||
ulong reg1, reg2;
|
||||
|
||||
if (p2) {
|
||||
reg1 = p1->reg;
|
||||
reg2 = p2->reg;
|
||||
}
|
||||
|
||||
else if (p1) {
|
||||
reg1 = RDI;
|
||||
reg2 = p1->reg;
|
||||
}
|
||||
|
||||
else {
|
||||
reg1 = RDI;
|
||||
reg2 = RSI;
|
||||
}
|
||||
|
||||
ulong x1 = readmem(ctx, R(reg1), len);
|
||||
ulong x2 = readmem(ctx, R(reg2), len);
|
||||
|
||||
COMPARE(x1, x2);
|
||||
|
||||
STR_MOVE(reg1, len);
|
||||
STR_MOVE(reg2, len);
|
||||
}
|
||||
|
||||
IMPL_START_0(cmpsb)
|
||||
{
|
||||
cmps_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(cmpsw)
|
||||
{
|
||||
cmps_impl(ctx, p1, p2, 2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(cmpsl)
|
||||
{
|
||||
cmps_impl(ctx, p1, p2, 4);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(cmpsq)
|
||||
{
|
||||
cmps_impl(ctx, p1, p2, 8);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void cmpzs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
{
|
||||
ulong reg1, reg2;
|
||||
|
||||
if (p2) {
|
||||
reg1 = p1->reg;
|
||||
reg2 = p2->reg;
|
||||
}
|
||||
|
||||
else if (p1) {
|
||||
reg1 = RDI;
|
||||
reg2 = p1->reg;
|
||||
}
|
||||
|
||||
else {
|
||||
reg1 = RDI;
|
||||
reg2 = RSI;
|
||||
}
|
||||
|
||||
ulong x1 = readmem(ctx, R(reg1), len);
|
||||
ulong x2 = readmem(ctx, R(reg2), len);
|
||||
|
||||
COMPARE(x1, x2);
|
||||
|
||||
if (!x1 && !x2)
|
||||
flg &= ~ZF;
|
||||
|
||||
STR_MOVE(reg1, len);
|
||||
STR_MOVE(reg2, len);
|
||||
}
|
||||
|
||||
IMPL_START_0(cmpzsb)
|
||||
{
|
||||
cmpzs_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(cmzpsw)
|
||||
{
|
||||
cmpzs_impl(ctx, p1, p2, 2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(cmpzsl)
|
||||
{
|
||||
cmpzs_impl(ctx, p1, p2, 4);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(cmpzsq)
|
||||
{
|
||||
cmpzs_impl(ctx, p1, p2, 8);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
{
|
||||
ulong reg1, reg2;
|
||||
|
||||
if (p2) {
|
||||
reg1 = p1->reg;
|
||||
reg2 = p2->reg;
|
||||
}
|
||||
|
||||
else if (p1) {
|
||||
reg1 = RDI;
|
||||
reg2 = p1->reg;
|
||||
}
|
||||
|
||||
else {
|
||||
reg1 = RDI;
|
||||
reg2 = RSI;
|
||||
}
|
||||
|
||||
ulong x = readmem(ctx, R(reg2), len);
|
||||
writemem(ctx, x, R(reg1), len);
|
||||
|
||||
flg = (x == 0 ? flg|ZF : flg&~ZF);
|
||||
|
||||
STR_MOVE(reg1, len);
|
||||
STR_MOVE(reg2, len);
|
||||
}
|
||||
|
||||
IMPL_START_0(movsb)
|
||||
{
|
||||
movs_impl(ctx, p1, p2, 1);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(movsw)
|
||||
{
|
||||
movs_impl(ctx, p1, p2, 2);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(movsl)
|
||||
{
|
||||
movs_impl(ctx, p1, p2, 4);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(movsq)
|
||||
{
|
||||
movs_impl(ctx, p1, p2, 8);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
|
10
vm/pc/decd.c
10
vm/pc/decd.c
@ -7,7 +7,7 @@
|
||||
// Imperatively read the "DECD" file before reading this code
|
||||
//
|
||||
|
||||
static void check_param_type(ctx_t *ctx, uint prm, uchar fmt)
|
||||
static void check_param_type(ctx_t *ctx, instr_t *in, uint prm, uchar fmt)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
@ -22,8 +22,8 @@ static void check_param_type(ctx_t *ctx, uint prm, uchar fmt)
|
||||
|
||||
if (!ok)
|
||||
_except(ctx, E_ILL,
|
||||
"FT1 or FT2 not matching INSTR's expected parameter types: "
|
||||
"fmt=0x%x prm=0x%x", fmt, prm);
|
||||
"FT1 or FT2 not matching %s's expected parameter types: "
|
||||
"fmt=0x%x prm=0x%x", in->full, fmt, prm);
|
||||
}
|
||||
|
||||
void decode(ctx_t *ctx)
|
||||
@ -102,7 +102,7 @@ skip_w2:
|
||||
return;
|
||||
}
|
||||
|
||||
check_param_type(ctx, in->prm1, f1);
|
||||
check_param_type(ctx, in, in->prm1, f1);
|
||||
extract_param(ctx, &p1, f1);
|
||||
|
||||
//
|
||||
@ -121,7 +121,7 @@ skip_w2:
|
||||
return;
|
||||
}
|
||||
|
||||
check_param_type(ctx, in->prm2, f2);
|
||||
check_param_type(ctx, in, in->prm2, f2);
|
||||
extract_param(ctx, &p2, f2);
|
||||
|
||||
exec_instr(ctx, in, &p1, &p2, lock, rep, cond, pc);
|
||||
|
10
vm/pc/dump.c
10
vm/pc/dump.c
@ -76,10 +76,10 @@ void dump_instr(ctx_t *ctx,
|
||||
log("0x%lX: ", pc);
|
||||
|
||||
if (lock)
|
||||
log("lock ");
|
||||
log("lock");
|
||||
|
||||
if (rep)
|
||||
log("rep ");
|
||||
log(" rep");
|
||||
|
||||
if (cond)
|
||||
{
|
||||
@ -96,7 +96,11 @@ void dump_instr(ctx_t *ctx,
|
||||
log("%s", cond_suffixes[cond]);
|
||||
}
|
||||
|
||||
log("\t");
|
||||
if (!rep)
|
||||
log("\t\t");
|
||||
|
||||
else
|
||||
log("\t");
|
||||
|
||||
log("%s\t", in->name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user