Assembler + Multitasking Virtual Machine, written in JavaScript
Select Program:
Hello World
Infinite Loop (A)
Infinite Loop (B)
Finite Loop
Write File
Read File
Delete File
Factorial
mov $0x48 0x00 # H mov $0x65 0x01 # e mov $0x6c 0x02 # l mov $0x6c 0x03 # l mov $0x6f 0x04 # o mov $0x20 0x05 mov $0x57 0x06 # W mov $0x6f 0x07 # o mov $0x72 0x08 # r mov $0x6c 0x09 # l mov $0x64 0x0a # d mov $0x21 0x0b # ! mov $0x00 0x0c # \0 mov $0x04 %eax # ax = 4 (syscall 4 = write) mov $0x01 %ebx # bx = 1 (stdout) mov $0x00 %ecx # cx = 0 (offset start of string) mov $0x0c %edx # dx = 12 (length of string) int $0x80 # interrupt 0x80 (syscall) mov $0x02 %ebx # bx = 2 (stderr = console) int $0x80 # interrupt 0x80 (syscall) jmp $0xffff # jump to 65536 (behind code = exit)
mov $0x41 0x00 # A mov $0x00 0x01 # \0 iteration: mov $0x04 %eax # ax = 4 (syscall 4 = write) mov $0x01 %ebx # bx = 1 (stdout) mov $0x00 %ecx # cx = 0 (offset start of string) mov $0x01 %edx # dx = 1 (length of string) int $0x80 # interrupt 0x80 (syscall) jmp iteration # infinite loop
mov $0x42 0x00 # B mov $0x00 0x01 # \0 iteration: nop nop nop nop nop nop # delay nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop mov $0x04 %eax # ax = 4 (syscall 4 = write) mov $0x01 %ebx # bx = 1 (stdout) mov $0x00 %ecx # cx = 0 (offset start of string) mov $0x01 %edx # dx = 1 (length of string) int $0x80 # interrupt 0x80 (syscall) jmp iteration # infinite loop
mov $0x41 0x00 # A mov $0x00 0x01 # \0 mov $0x00 0x02 # i = 0 iteration: mov $0x04 %eax # ax = 4 (syscall 4 = write) mov $0x01 %ebx # bx = 1 (stdout) mov $0x00 %ecx # cx = 0 (offset start of string) mov $0x01 %edx # dx = 1 (length of string) int $0x80 # interrupt 0x80 (syscall) add $0x01 0x02 cmp $0xf0 0x02 # 240 iterations jne iteration jmp $0xffff # jump to 65536 (behind code = exit)
mov $0x48 0x00 mov $0x65 0x01 mov $0x6c 0x02 # Hel mov $0x6c 0x03 mov $0x6f 0x04 mov $0x00 0x05 # lo\0 mov $0x68 0x06 mov $0x65 0x07 mov $0x6c 0x08 # hel mov $0x6c 0x09 mov $0x6f 0x0a mov $0x2e 0x0b # lo. mov $0x74 0x0c mov $0x78 0x0d mov $0x74 0x0e # txt mov $0x00 0x0f # \0 mov $0x05 %eax # syscall 5 = open file mov $0x06 %ebx # filename mov $0x700 %ecx # create / overwrite mode int $0x80 # execute syscall mov %eax %ebx # move file handle to ebx mov $0x04 %eax # syscall 4 = write mov $0x00 %ecx # start of string mov $0x05 %edx # length of string int $0x80 # execute syscall mov $0x06 %eax # syscall 6 = close file #mov ... %ebx # (file handle is still in ebx) int $0x80 # execute syscall
mov $0x00 0x00 mov $0x00 0x01 mov $0x00 0x02 # buffer mov $0x00 0x03 mov $0x00 0x04 mov $0x00 0x05 # mov $0x68 0x06 mov $0x65 0x07 mov $0x6c 0x08 # hel mov $0x6c 0x09 mov $0x6f 0x0a mov $0x2e 0x0b # lo. mov $0x74 0x0c mov $0x78 0x0d mov $0x74 0x0e # txt mov $0x00 0x0f # \0 mov $0x05 %eax # syscall 5 = open file mov $0x06 %ebx # filename mov $0x00 %ecx # read mode int $0x80 # execute syscall mov %eax %ebx # move file handle to ebx mov $0x03 %eax # syscall 3 = read mov $0x00 %ecx # start of buffer mov $0x05 %edx # length of buffer int $0x80 # execute syscall mov $0x06 %eax # syscall 6 = close file #mov ... %ebx # (file handle is still in ebx) int $0x80 # execute syscall mov $0x04 %eax # syscall 4 = write mov $0x01 %ebx # stdout #mov $0x00 %ecx # start of string still in ecx #mov $0x05 %edx # length of string still in edx int $0x80 # execute syscall
mov $0x68 0x00 mov $0x65 0x01 mov $0x6c 0x02 # hel mov $0x6c 0x03 mov $0x6f 0x04 mov $0x2e 0x05 # lo. mov $0x74 0x06 mov $0x78 0x07 mov $0x74 0x08 # txt mov $0x00 0x09 # \0 mov $0x0a %eax # syscall 10 = delete file mov $0x00 %ebx # filename int $0x80 # execute syscall
mov $0x05 %eax # compute the factorial of 5 call factorial mov $0x0a %ecx # print the result call print mov $0x01 %eax # exit int $0x80 factorial: cmp %eax $0x01 # if(eax == 1) jne factorialexec # return 1 ret factorialexec: push %eax # store eax sub $0x01 %eax # get factorial of eax-1 call factorial pop %ebx # get old eax to ebx mul %ebx %eax # multiply it onto eax ret print: mov %ecx %edx # edx = ecx nextdigit: sub $0x01 %ecx # ecx-- mov %eax (%ecx) # get (eax % 10)+'0' to *ecx mod $0x0a (%ecx) add $0x30 (%ecx) div $0x0a %eax # eax /= 10 cmp %eax $0x00 jne nextdigit mov $0x04 %eax # write mov $0x01 %ebx # stdout sub %ecx %edx # edx -= ecx int $0x80 ret
Execute
Reset
Clear
Hint: the syntax is similar to GNU Assembler
Supported opcodes:
general statements
nop, mov, cmp
jump statements
jmp, je, jne
arithmetic operations
add, sub, mul, div, mod
stack
push, pop, call, ret
interrupts
int
Registers: %eax, %ebx, %ecx, %edx
Todo: more jump conditions, killing processes.