cleanup / prepwork for assembler.
This commit is contained in:
parent
2d72240652
commit
922959191d
|
@ -16,4 +16,7 @@ typedef int32_t i32;
|
|||
|
||||
#define USED(x) ((void)(x))
|
||||
|
||||
#define AS_INT(v) ((i32)(v))
|
||||
#define AS_UINT(v) ((u32)(v))
|
||||
|
||||
#endif
|
||||
|
|
132
src/opcodes.h
132
src/opcodes.h
|
@ -4,55 +4,57 @@
|
|||
#include "common.h"
|
||||
|
||||
typedef enum {
|
||||
OP_HALT, /* halt : terminate execution */
|
||||
OP_JMP, /* jump : jump to address dest unconditionally */
|
||||
OP_JMPF, /* jmpf : jump to address dest if flag is ne 0 */
|
||||
OP_CALL, /* call : creates a new frame */
|
||||
OP_RETURN, /* retn : returns from a frame to the parent frame */
|
||||
OP_LOAD, /* load : dest = &[next memory location] */
|
||||
OP_LOAD_IMM, /* load : dest = &[next memory location] */
|
||||
OP_STORE, /* stor : next memory location = src1 as float */
|
||||
OP_PUSH, /* push : push str ref from register onto the stack and copy str */
|
||||
OP_POP, /* pop : pop int from stack onto the register */
|
||||
OP_REG_MOV, /* rmov : dest = src1 */
|
||||
OP_SYSCALL, /* sysc : */
|
||||
OP_ADD_INT, /* addi : dest = src1 + src2 */
|
||||
OP_SUB_INT, /* subi : dest = src1 - src2 */
|
||||
OP_MUL_INT, /* muli : dest = src1 * src2 */
|
||||
OP_DIV_INT, /* divi : dest = src1 / src2 */
|
||||
OP_ADD_UINT, /* addu : dest = src1 + src2 */
|
||||
OP_SUB_UINT, /* subu : dest = src1 - src2 */
|
||||
OP_MUL_UINT, /* mulu : dest = src1 * src2 */
|
||||
OP_DIV_UINT, /* divu : dest = src1 / src2 */
|
||||
OP_ADD_REAL, /* addr : dest = src1 + src2 */
|
||||
OP_SUB_REAL, /* subr : dest = src1 - src2 */
|
||||
OP_MUL_REAL, /* mulr : dest = src1 * src2 */
|
||||
OP_DIV_REAL, /* divr : dest = src1 / src2 */
|
||||
OP_INT_TO_REAL, /* itor : dest = src1 as real */
|
||||
OP_UINT_TO_REAL, /* utor : dest = src1 as real */
|
||||
OP_REAL_TO_INT, /* rtoi : dest = src1 as int */
|
||||
OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */
|
||||
OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */
|
||||
OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/
|
||||
OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */
|
||||
OP_JLE_INT, /* jlei : jump to address dest if src1 as int <= src2 as int */
|
||||
OP_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/
|
||||
OP_JEQ_UINT, /* jequ : jump to address dest if src1 as int == src2 as uint */
|
||||
OP_JGT_UINT, /* jgtu : jump to address dest if src1 as int > src2 as uint*/
|
||||
OP_JLT_UINT, /* jltu : jump to address dest if src1 as int < src2 as uint */
|
||||
OP_JLE_UINT, /* jleu : jump to address dest if src1 as int <= src2 as uint */
|
||||
OP_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/
|
||||
OP_JEQ_REAL, /* jeqr : jump to address dest if src1 as real == src2 as real */
|
||||
OP_JGE_REAL, /* jgtr : jump to address dest if src1 as real >= src2 as real */
|
||||
OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */
|
||||
OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */
|
||||
OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */
|
||||
OP_STRLEN, /* strl : dest = length of str at src1 ptr */
|
||||
OP_STREQ, /* steq : dest = src1 ptr string == src2 ptr string */
|
||||
OP_STRCAT, /* scat : dest = ptr of src1 ptr string + src2 ptr string */
|
||||
OP_STR_GET_CHAR, /* sgch : dest = ptr of src1 ptr string, src2 index of string */
|
||||
OP_STR_FIND_CHAR, /* sfch : dest = ptr of src1 ptr string, src2 uint8 char */
|
||||
OP_STR_SLICE, /* ssli : dest = ptr of src1 ptr string, src2 start index, src3 end index */
|
||||
OP_HALT, /* halt : terminate execution */
|
||||
OP_JMP, /* jump : jump to address dest unconditionally */
|
||||
OP_JMPF, /* jmpf : jump to address dest if flag is ne 0 */
|
||||
OP_CALL, /* call : creates a new frame */
|
||||
OP_RETURN, /* retn : returns from a frame to the parent frame */
|
||||
OP_LOAD, /* load : dest = &[next memory location] */
|
||||
OP_LOAD_IMM, /* load : dest = &[next memory location] */
|
||||
OP_STORE, /* stor : next memory location = src1 as float */
|
||||
OP_PUSH, /* push : push str ref from register onto the stack and copy str */
|
||||
OP_POP, /* pop : pop int from stack onto the register */
|
||||
OP_REG_MOV, /* rmov : dest = src1 */
|
||||
OP_SYSCALL, /* sysc : */
|
||||
OP_ADD_INT, /* addi : dest = src1 + src2 */
|
||||
OP_SUB_INT, /* subi : dest = src1 - src2 */
|
||||
OP_MUL_INT, /* muli : dest = src1 * src2 */
|
||||
OP_DIV_INT, /* divi : dest = src1 / src2 */
|
||||
OP_ADD_UINT, /* addu : dest = src1 + src2 */
|
||||
OP_SUB_UINT, /* subu : dest = src1 - src2 */
|
||||
OP_MUL_UINT, /* mulu : dest = src1 * src2 */
|
||||
OP_DIV_UINT, /* divu : dest = src1 / src2 */
|
||||
OP_ADD_REAL, /* addr : dest = src1 + src2 */
|
||||
OP_SUB_REAL, /* subr : dest = src1 - src2 */
|
||||
OP_MUL_REAL, /* mulr : dest = src1 * src2 */
|
||||
OP_DIV_REAL, /* divr : dest = src1 / src2 */
|
||||
OP_INT_TO_REAL, /* itor : dest = src1 as real */
|
||||
OP_UINT_TO_REAL, /* utor : dest = src1 as real */
|
||||
OP_REAL_TO_INT, /* rtoi : dest = src1 as int */
|
||||
OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */
|
||||
OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */
|
||||
OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/
|
||||
OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */
|
||||
OP_JLE_INT, /* jlei : jump to address dest if src1 as int <= src2 as int */
|
||||
OP_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/
|
||||
OP_JEQ_UINT, /* jequ : jump to address dest if src1 as int == src2 as uint */
|
||||
OP_JGT_UINT, /* jgtu : jump to address dest if src1 as int > src2 as uint*/
|
||||
OP_JLT_UINT, /* jltu : jump to address dest if src1 as int < src2 as uint */
|
||||
OP_JLE_UINT, /* jleu : jump to address dest if src1 as int <= src2 as uint */
|
||||
OP_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/
|
||||
OP_JEQ_REAL, /* jeqr : jump to address dest if src1 as real == src2 as real */
|
||||
OP_JGE_REAL, /* jgtr : jump to address dest if src1 as real >= src2 as real */
|
||||
OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */
|
||||
OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */
|
||||
OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */
|
||||
OP_STRLEN, /* strl : dest = length of str at src1 ptr */
|
||||
OP_STREQ, /* steq : dest = src1 ptr string == src2 ptr string */
|
||||
OP_STRCAT, /* scat : dest = ptr of src1 ptr string + src2 ptr string */
|
||||
OP_STR_GET_CHAR, /* sgch : dest = ptr of src1 ptr string, src2 index of string
|
||||
*/
|
||||
OP_STR_FIND_CHAR, /* sfch : dest = ptr of src1 ptr string, src2 uint8 char */
|
||||
OP_STR_SLICE, /* ssli : dest = ptr of src1 ptr string, src2 start index, src3
|
||||
end index */
|
||||
OP_INT_TO_STRING, /* itos : dest = src1 as str */
|
||||
OP_UINT_TO_STRING, /* utos : dest = src1 as str */
|
||||
OP_REAL_TO_STRING, /* rtos : dest = src1 as str */
|
||||
|
@ -99,38 +101,30 @@ typedef struct device_s {
|
|||
} Device;
|
||||
|
||||
#define MEMORY_SIZE 1024 /*(640 * 480 + 65536)*/
|
||||
#define CODE_SIZE 128 /*8192*/
|
||||
#define CODE_SIZE 128 /*8192*/
|
||||
#define FRAMES_SIZE 128
|
||||
#define STACK_SIZE 256
|
||||
#define DEVICES_SIZE 8
|
||||
typedef struct vm_s {
|
||||
u32 pc; /* program counter */
|
||||
u32 cp; /* code pointer (last allocated opcode) */
|
||||
u32 fp; /* frame pointer (current frame) */
|
||||
u32 sp; /* stack pointer (top of stack) */
|
||||
u32 rp; /* return stack pointer (top of stack) */
|
||||
u32 mp; /* memory pointer (last allocated value) */
|
||||
u32 dc; /* device count */
|
||||
u32 flag; /* flag (temporary results like SYSCALL status) */
|
||||
Frame frames[FRAMES_SIZE]; /* function call frames */
|
||||
u32 stack[STACK_SIZE]; /* main stack */
|
||||
u32 pc; /* program counter */
|
||||
u32 cp; /* code pointer (last allocated opcode) */
|
||||
u32 fp; /* frame pointer (current frame) */
|
||||
u32 sp; /* stack pointer (top of stack) */
|
||||
u32 rp; /* return stack pointer (top of stack) */
|
||||
u32 mp; /* memory pointer (last allocated value) */
|
||||
u32 dc; /* device count */
|
||||
u32 flag; /* flag (temporary results like SYSCALL status) */
|
||||
Frame frames[FRAMES_SIZE]; /* function call frames */
|
||||
u32 stack[STACK_SIZE]; /* main stack */
|
||||
u32 return_stack[STACK_SIZE]; /* return stack (for call recursion) */
|
||||
Device devices[DEVICES_SIZE]; /* device definitions */
|
||||
u8 code[CODE_SIZE]; /* code block */
|
||||
u8 memory[MEMORY_SIZE]; /* memory block */
|
||||
} VM;
|
||||
|
||||
#define AS_INT(v) ((i32)(v))
|
||||
#define AS_UINT(v) ((u32)(v))
|
||||
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
|
||||
#define TO_FIXED(f) ((u32)((i32)( \
|
||||
((f) >= 0.0f) ? ((f) * 65536.0f + 0.5f) : ((f) * 65536.0f - 0.5f) \
|
||||
)))
|
||||
|
||||
#define read_u8(vm, location, addr) ((vm)->location[addr])
|
||||
#define read_u16(vm, location, addr) \
|
||||
(((uint16_t)(vm)->location[(addr)] << 8) | \
|
||||
((uint16_t)(vm)->location[(addr) + 1]))
|
||||
(((u16)(vm)->location[(addr)] << 8) | ((u16)(vm)->location[(addr) + 1]))
|
||||
#define read_u32(vm, location, addr) \
|
||||
(((u32)(vm)->location[(addr)] << 24) | \
|
||||
((u32)(vm)->location[(addr) + 1] << 16) | \
|
||||
|
|
106
src/str.c
106
src/str.c
|
@ -41,4 +41,108 @@ u32 strnlen(const char *str, u32 max_len) {
|
|||
; /* twiddle thumbs, 'i' is doing all the work*/
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Static digit lookup table (0-9) */
|
||||
const char digits[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||
|
||||
/* Writes decimal digits of 'value' backwards into 'buf_end' (inclusive),
|
||||
stopping at 'buf_start'. Returns pointer to first written digit. */
|
||||
char *write_digits_backwards(u32 value, char *buf_end, char *buf_start) {
|
||||
char *p = buf_end;
|
||||
if (value == 0) {
|
||||
*--p = '0';
|
||||
} else {
|
||||
u32 num = value;
|
||||
while (num && p > buf_start) {
|
||||
*--p = digits[num % 10];
|
||||
num /= 10;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void uint_to_string(u32 value, char *buffer) {
|
||||
char temp[16];
|
||||
char *start;
|
||||
char *end = temp + sizeof(temp) - 1;
|
||||
*end = '\0';
|
||||
start = write_digits_backwards(value, end, temp);
|
||||
strcopy(buffer, start, end - start + 1); /* +1 for null terminator */
|
||||
}
|
||||
|
||||
void int_to_string(i32 value, char *buffer) {
|
||||
char temp[17]; /* Extra space for '-' */
|
||||
i32 negative = 0;
|
||||
u32 abs_value;
|
||||
char *end = temp + sizeof(temp) - 1;
|
||||
*end = '\0';
|
||||
|
||||
if (value == (-2147483647 - 1)) { /* INT32_MIN */
|
||||
strcopy(buffer, "-2147483648", 12);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value == 0) {
|
||||
*--end = '0';
|
||||
} else {
|
||||
if (value < 0) {
|
||||
negative = 1;
|
||||
abs_value = (u32)(-value);
|
||||
} else {
|
||||
abs_value = (u32)value;
|
||||
}
|
||||
|
||||
end = write_digits_backwards(abs_value, end, temp);
|
||||
|
||||
if (negative) {
|
||||
*--end = '-';
|
||||
}
|
||||
}
|
||||
|
||||
strcopy(buffer, end, temp + sizeof(temp) - end);
|
||||
}
|
||||
|
||||
void fixed_to_string(i32 value, char *buffer) {
|
||||
char temp[32];
|
||||
i32 negative;
|
||||
u32 int_part;
|
||||
u32 frac_part, frac_digits;
|
||||
char *end = temp + sizeof(temp) - 1;
|
||||
*end = '\0';
|
||||
|
||||
negative = 0;
|
||||
if (value < 0) {
|
||||
negative = 1;
|
||||
value = -value;
|
||||
}
|
||||
|
||||
int_part = AS_UINT(value >> 16);
|
||||
frac_part = AS_UINT(value & 0xFFFF);
|
||||
|
||||
/* Convert fractional part to 5 decimal digits */
|
||||
frac_digits = (frac_part * 100000U) / 65536U;
|
||||
|
||||
/* Trim trailing zeros */
|
||||
while (frac_digits > 0 && frac_digits % 10 == 0) {
|
||||
frac_digits /= 10;
|
||||
}
|
||||
|
||||
if (frac_digits > 0) {
|
||||
end = write_digits_backwards(frac_digits, end, temp);
|
||||
*--end = '.';
|
||||
}
|
||||
|
||||
if (int_part == 0 && frac_digits == 0) {
|
||||
*--end = '0';
|
||||
} else {
|
||||
end = write_digits_backwards(int_part, end, temp);
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
*--end = '-';
|
||||
}
|
||||
|
||||
strcopy(buffer, end, temp + sizeof(temp) - end);
|
||||
}
|
||||
|
|
|
@ -6,5 +6,8 @@
|
|||
i32 strcopy(char* to, const char *from, u32 length);
|
||||
u32 strlen(const char* str);
|
||||
bool streq(const char *s1, const char *s2);
|
||||
char *write_digits_backwards(u32 value, char *buf_end, char *buf_start);
|
||||
void int_to_string(i32 value, char *buffer);
|
||||
void fixed_to_string(i32 value, char *buffer);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,8 +48,7 @@ bool compile_internal_test(const char *filename, VM *vm) {
|
|||
|
||||
bool test_simple_compile(VM *vm) {
|
||||
u32 ptr;
|
||||
u32 newline_addr =
|
||||
str_alloc(vm, &vm->frames[vm->fp], "\n", 2);
|
||||
/*u32 newline_addr = str_alloc(vm, &vm->frames[vm->fp], "\n", 2);*/
|
||||
u32 terminal_path_addr =
|
||||
str_alloc(vm, &vm->frames[vm->fp], "/dev/term/0", 12);
|
||||
vm->code[vm->cp++] = OP_LOAD;
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
#include "opcodes.h"
|
||||
|
||||
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
|
||||
#define TO_FIXED(f) ((u32)((i32)( \
|
||||
((f) >= 0.0f) ? ((f) * 65536.0f + 0.5f) : ((f) * 65536.0f - 0.5f) \
|
||||
)))
|
||||
|
||||
/* Test function type definition */
|
||||
typedef bool (*TestFunction)(VM *vm);
|
||||
|
||||
|
|
103
src/vm.c
103
src/vm.c
|
@ -488,106 +488,3 @@ bool step_vm(VM *vm) {
|
|||
}
|
||||
return false; /* something bad happened */
|
||||
}
|
||||
|
||||
/* Static digit lookup table (0-9) */
|
||||
const char digits[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||
|
||||
/* Writes decimal digits of 'value' backwards into 'buf_end' (inclusive),
|
||||
stopping at 'buf_start'. Returns pointer to first written digit. */
|
||||
char *write_digits_backwards(u32 value, char *buf_end, char *buf_start) {
|
||||
char *p = buf_end;
|
||||
if (value == 0) {
|
||||
*--p = '0';
|
||||
} else {
|
||||
u32 num = value;
|
||||
while (num && p > buf_start) {
|
||||
*--p = digits[num % 10];
|
||||
num /= 10;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void uint_to_string(u32 value, char *buffer) {
|
||||
char temp[16];
|
||||
char *start;
|
||||
char *end = temp + sizeof(temp) - 1;
|
||||
*end = '\0';
|
||||
start = write_digits_backwards(value, end, temp);
|
||||
strcopy(buffer, start, end - start + 1); /* +1 for null terminator */
|
||||
}
|
||||
|
||||
void int_to_string(i32 value, char *buffer) {
|
||||
char temp[17]; /* Extra space for '-' */
|
||||
i32 negative = 0;
|
||||
u32 abs_value;
|
||||
char *end = temp + sizeof(temp) - 1;
|
||||
*end = '\0';
|
||||
|
||||
if (value == (-2147483647 - 1)) { /* INT32_MIN */
|
||||
strcopy(buffer, "-2147483648", 12);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value == 0) {
|
||||
*--end = '0';
|
||||
} else {
|
||||
if (value < 0) {
|
||||
negative = 1;
|
||||
abs_value = (u32)(-value);
|
||||
} else {
|
||||
abs_value = (u32)value;
|
||||
}
|
||||
|
||||
end = write_digits_backwards(abs_value, end, temp);
|
||||
|
||||
if (negative) {
|
||||
*--end = '-';
|
||||
}
|
||||
}
|
||||
|
||||
strcopy(buffer, end, temp + sizeof(temp) - end);
|
||||
}
|
||||
|
||||
void fixed_to_string(i32 value, char *buffer) {
|
||||
char temp[32];
|
||||
i32 negative;
|
||||
u32 int_part;
|
||||
u32 frac_part, frac_digits;
|
||||
char *end = temp + sizeof(temp) - 1;
|
||||
*end = '\0';
|
||||
|
||||
negative = 0;
|
||||
if (value < 0) {
|
||||
negative = 1;
|
||||
value = -value;
|
||||
}
|
||||
|
||||
int_part = AS_UINT(value >> 16);
|
||||
frac_part = AS_UINT(value & 0xFFFF);
|
||||
|
||||
/* Convert fractional part to 5 decimal digits */
|
||||
frac_digits = (frac_part * 100000U) / 65536U;
|
||||
|
||||
/* Trim trailing zeros */
|
||||
while (frac_digits > 0 && frac_digits % 10 == 0) {
|
||||
frac_digits /= 10;
|
||||
}
|
||||
|
||||
if (frac_digits > 0) {
|
||||
end = write_digits_backwards(frac_digits, end, temp);
|
||||
*--end = '.';
|
||||
}
|
||||
|
||||
if (int_part == 0 && frac_digits == 0) {
|
||||
*--end = '0';
|
||||
} else {
|
||||
end = write_digits_backwards(int_part, end, temp);
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
*--end = '-';
|
||||
}
|
||||
|
||||
strcopy(buffer, end, temp + sizeof(temp) - end);
|
||||
}
|
||||
|
|
63
test/fib.asm
63
test/fib.asm
|
@ -1,29 +1,34 @@
|
|||
main:
|
||||
lodi $0 35
|
||||
pshi $0
|
||||
call &fib
|
||||
popi $0
|
||||
itos $1 $0
|
||||
puts $1
|
||||
halt
|
||||
fib:
|
||||
popi $0
|
||||
lodi $1 2
|
||||
lodi $2 &base_case
|
||||
jlti $2 $0 $1
|
||||
lodi $2 2
|
||||
subi $4 $0 $3
|
||||
pshi $4
|
||||
call &fib
|
||||
lodi $2 1
|
||||
subi $4 $0 $3
|
||||
pshi $4
|
||||
call &fib
|
||||
popi $4
|
||||
popi $5
|
||||
addi $6 $5 $4
|
||||
pshi $6
|
||||
retn
|
||||
base_case:
|
||||
pshi $0
|
||||
retn
|
||||
.text
|
||||
main:
|
||||
load $0 35
|
||||
push $0
|
||||
call &fib
|
||||
pop $0
|
||||
itos $1 $0
|
||||
load $2, &terminal_str
|
||||
slen $4, $3
|
||||
sysc DEVICE_WRITE, 3, $2 ; print(sum.toS())
|
||||
halt
|
||||
fib:
|
||||
popi $0
|
||||
load $1 2
|
||||
lodi $2 &base_case
|
||||
jlti $2 $0 $1
|
||||
load $2 2
|
||||
subi $4 $0 $3
|
||||
push $4
|
||||
call &fib
|
||||
load $2 1
|
||||
subi $4 $0 $3
|
||||
push $4
|
||||
call &fib
|
||||
pop $4
|
||||
pop $5
|
||||
addi $6 $5 $4
|
||||
push $6
|
||||
retn
|
||||
base_case:
|
||||
push $0
|
||||
retn
|
||||
.data
|
||||
terminal_str: "/dev/term/0"
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
.text
|
||||
hello:
|
||||
"nuqneH 'u'?"
|
||||
puts &hello
|
||||
load $1 &hello_str
|
||||
load $2, &terminal_str
|
||||
slen $4, $3
|
||||
sysc DEVICE_WRITE, 3, $2 ; print(sum.toS())
|
||||
halt
|
||||
|
||||
|
||||
.data
|
||||
terminal_str: "/dev/term/0"
|
||||
hello_str: "nuqneH 'u'?"
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
.text
|
||||
main:
|
||||
loadu $0 1
|
||||
loadu $1 2
|
||||
limm $0 1.0
|
||||
limm $1 2.0
|
||||
addu $2 $1 $0
|
||||
utos $3 $2
|
||||
puts $3
|
||||
halt
|
||||
load $2, &terminal_str
|
||||
slen $4, $3
|
||||
sysc DEVICE_WRITE, 3, $2 ; print(sum.toS())
|
||||
halt
|
||||
|
||||
.data
|
||||
terminal_str: "/dev/term/0"
|
||||
|
Loading…
Reference in New Issue