From 9a6c7d85eb1be819b94d0feb0cb84de8546e36fd Mon Sep 17 00:00:00 2001 From: "Sebastian G. Kirmayer" Date: Tue, 7 Jul 2026 23:54:15 +0200 Subject: 0.1 --- start.asm | 456 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 456 insertions(+) create mode 100644 start.asm (limited to 'start.asm') diff --git a/start.asm b/start.asm new file mode 100644 index 0000000..b2bef32 --- /dev/null +++ b/start.asm @@ -0,0 +1,456 @@ +# Copyright (C) 2026 Sebastian G. Kirmayer +# +# This file is part of sysf-i386. +# +# sysf-i386 is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# sysf-i386 is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along +# with sysf-i386. If not, see . +# + +# Syscall numbers +NR_exit=1 +NR_read=3 +NR_write=4 +NR_open=5 +NR_close=6 +NR_brk=45 + +text +label _start + call init_heap + + # option parsing + leal @%esp+4 %ebp + +L loop + addl 4 %ebp + movl @%ebp %ebx + testl %ebx %ebx + jz done. + movb @%ebx %cl + cmpb 0x2D %cl # - + jne filename. + incl %ebx + movb @%ebx %cl + cmpb 0x00 %cl + je filename. + cmpb 0x2D %cl # - + je longopt. + cmpb 0x3F %cl # ? + je usage + cmpb 0x56 %cl # V + je print_version + jmp bad_usage + +L longopt + incl %ebx + movb @%ebx %cl + cmpb 0x00 %cl + je opts_end. + movl %ebx %eax + call strnul + pushl %eax + pushl %eax + movl flag_version %eax + movl flag_version_end %ecx + movl %ebx %edx + call streq + je print_version + movl flag_help %eax + movl flag_help_end %ecx + movl %ebx %edx + call streq + je usage + jmp bad_usage + +L opts_end + addl 4 %ebp + movl @%ebp %ebx + testl %ebx %ebx + jz done. +L filename + movl @%ebp+4 %eax + testl %eax %eax + jnz bad_usage + movl @%ebp %ebx + movb @%ebx %cl + cmpb 0x2D %cl + jne open_file. + movb @%ebx %cl + cmpb 0x00 %cl + je done. +L open_file + movl $NR_open %eax + xorl %ecx %ecx + int 0x80 + testl %eax %eax + js open_failed. + movl %eax %edi + movl @heap_ptr %esi + call slurp + movl %edi %ebx + movl $NR_close %eax + int 0x80 + movl %esi %ebx + jmp slurped. + +L open_failed + stderr 'Failed to open ' + movl %ebx %eax + call strnul + movl %eax %ecx + movl %ebx %eax + call stderr + stderr ' +' + jmp error + +L done + # slurp(stdin) + xorl %eax %eax + movl @heap_ptr %ebx + call slurp +L slurped + # parse(slurped code) + movl %ebx %eax + movl @heap_ptr %ecx + call parse + call ty_top + movl %eax %ebx + call ty_main + call ty_top + movl %ebx %ecx + call ty_eq + jne bad_main. + movl @heap_ptr %eax + jmp execute + +L bad_main + stderr 'Bad main type: ' + movl %ebx %eax + call ty_stderr + stderr ' +' + jmp error + +label ty_main + # fix + movl 0 %eax + call ty_var + movl 1 %eax + call ty_var + call ty_arrow + movl 0 %eax + call ty_var + movl 1 %eax + call ty_var + call ty_arrow + call ty_arrow + movl 0 %eax + call ty_var + movl 1 %eax + call ty_var + call ty_arrow + call ty_arrow + call ty_forall + # read + movl 0 %eax + call ty_var + movl 0 %eax + call ty_var + movl 0 %eax + call ty_var + movl 0 %eax + call ty_var + call ty_arrow + call ty_arrow + call ty_arrow + # write0 + movl 0 %eax + call ty_var + movl 0 %eax + call ty_var + call ty_arrow + # write1 + movl 0 %eax + call ty_var + movl 0 %eax + call ty_var + call ty_arrow + # exit + movl 0 %eax + call ty_var + movl 0 %eax + call ty_var + call ty_arrow + call ty_arrow + call ty_arrow + call ty_arrow + call ty_arrow + call ty_forall + ret + +label slurp # (fd: i32) -> () + pushl %ebx + movl %eax %ebx + # %ebx: file descriptor +L start + movl @heap_ptr %ecx + movl @heap_end %edx +L loop + subl %ecx %edx + jz alloc. + movl $NR_read %eax + int 0x80 + addl %ecx %edx + testl %eax %eax + js fail. + jz done. + addl %eax %ecx + jmp loop^ +L alloc + movl %ecx @heap_ptr + call alloc + jmp start^ +L done + movl %ecx @heap_ptr + popl %ebx + ret +L fail + stderr 'Failed to read program +' + jmp error + +bss +align +label heap_ptr + long 0 +label heap_end + long 0 + +text +label init_heap # () -> () + movl %ebx %ecx + xorl %ebx %ebx + movl $NR_brk %eax + int 0x80 + movl %eax @heap_ptr + movl %eax @heap_end + movl %ecx %ebx + ret + +label align_heap # () -> () + movl @heap_ptr %eax + addl 3 %eax + andl $((~3)) %eax + movl %eax @heap_ptr + ret + +label alloc # () -> () + movl %ebx %ecx + movl @heap_end %ebx + addl 0x1000 %ebx + movl $NR_brk %eax + int 0x80 + cmpl %eax %ebx + jne error + movl %eax @heap_end + movl %ecx %ebx + ret + +bss +label buffer_start + skip 0x100 +label buffer_cap buffer_start +align +label buffer_pos + long 0 +label buffer_len + long 0 +text + +# -1: EOF +# 0: 0 +# 1: 1 +label read # () -> (bit: i32) + movl @buffer_pos %ecx + movl %ecx %edx + shrl 3 %edx + cmpl @buffer_len %edx + je read. + xorl %eax %eax + movb @buffer_start+%edx %al + andl 7 %ecx + shrl %cl %eax + andl 1 %eax + incl @buffer_pos + ret + +L read + pushl %ebx + xorl %ebx %ebx + movl buffer_start %ecx + movl buffer_cap %edx + movl $NR_read %eax + int 0x80 + popl %ebx + testl %eax %eax + js error. + jz eof. + movl %eax @buffer_len + movl 0 @buffer_pos + jmp read + +L eof + movl -1 %eax + ret + +L error + stderr 'Error reading from stdin +' + jmp error + +bss +label write_buf + byte 0 +label write_bit + byte 0 +text + +label write0 + movl 0 %eax + jmp write. +label write1 + movl 1 %eax +L write + xorl %ecx %ecx + movb @write_bit %cl + shll %cl %eax + orb %al @write_buf + incb %cl + cmpb 8 %cl + je do_write. + movb %cl @write_bit + ret +L do_write + movb 0 @write_bit + pushl %ebx + movl 1 %ebx + movl write_buf %ecx + movl 1 %edx + movl $NR_write %eax + int 0x80 + popl %ebx + movb 0 @write_buf + ret + +label exit + movl $NR_exit %eax + xorl %ebx %ebx + int 0x80 + +label usage + call print_usage + jmp exit + +label bad_usage + call print_usage + jmp error + +label print_usage + movl 1 %ebx + movl usage_info %ecx + movl usage_info_len %edx + movl $NR_write %eax + int 0x80 + ret + +label print_version + movl 1 %ebx + movl version_info %ecx + movl version_info_len %edx + movl $NR_write %eax + int 0x80 + jmp exit + +label error + movl $NR_exit %eax + movl 1 %ebx + int 0x80 + +label stderr + pushl %ebx + movl %ecx %edx + movl %eax %ecx + subl %eax %edx + movl 2 %ebx + movl $NR_write %eax + int 0x80 + popl %ebx + ret + +label stderr_lineno + pushl %ebx + pushl %ebp + movl %esp %ebp + movl %esp %ebx + subl 0x20 %esp + subl 2 %ebx + movb 0x3A @%ebx + movb 0x20 @%ebx+1 + movl @lineno %eax + movl 10 %ecx +L loop + xorl %edx %edx + divl %ecx + addl 0x30 %edx + decl %ebx + movb %dl @%ebx + testl %eax %eax + jnz loop^ + subl 5 %ebx + movb 0x4C @%ebx + movb 0x69 @%ebx+1 + movb 0x6E @%ebx+2 + movb 0x65 @%ebx+3 + movb 0x20 @%ebx+4 + movl %ebx %eax + movl %ebp %ecx + call stderr + movl %ebp %esp + popl %ebp + popl %ebx + ret + +label report_error + pushl %eax + pushl %ecx + call stderr_lineno + popl %ecx + popl %eax + call stderr + ret + +rodata +string flag_version "version" +string flag_help "help" + +string version_info "\ +sysf-i386 $SYSF_VERSION +Copyright (C) 2026 Sebastian G. Kirmayer, GNU GPLv3+ +" + +string usage_info "\ +Usage: + sysf FILENAME + sysf --version +" -- cgit v1.2.3