summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-02-13 15:07:26 -0500
committerpommicket <pommicket@gmail.com>2022-02-13 15:07:26 -0500
commit2fef6981954df735f1f364e96c365c6f000a638b (patch)
tree4abd706106bc8e4df66cdbfdde8dea0de50f2e6f
parent6acd24e315c4351294c7f2e9b88fdd5faf48b966 (diff)
first C hello world!
-rw-r--r--05/codegen.b4
-rw-r--r--05/constants.b3
-rw-r--r--05/main.c85
-rw-r--r--05/parse.b4
-rw-r--r--05/preprocess.b6
-rw-r--r--05/stdarg.h4
-rw-r--r--README.md5
7 files changed, 66 insertions, 45 deletions
diff --git a/05/codegen.b b/05/codegen.b
index d33eb3e..d42d097 100644
--- a/05/codegen.b
+++ b/05/codegen.b
@@ -762,7 +762,6 @@ function generate_cast_top_of_stack
if *1to == TYPE_VOID goto gen_cast_to_void
if *1from == TYPE_VOID goto bad_gen_cast ; cast from void to something - that's bad
- if *1from == TYPE_ARRAY goto bad_gen_cast ; cast array (this probably won't ever happen because of decaying)
if *1to == TYPE_ARRAY goto bad_gen_cast ; cast to array
if *1from == TYPE_FUNCTION goto bad_gen_cast ; shouldn't happen
if *1to == TYPE_FUNCTION goto bad_gen_cast ; shouldn't happen
@@ -793,6 +792,7 @@ function generate_cast_top_of_stack
emit_add_rsp_imm32(c)
return
:gen_cast_to_integer
+ if *1from == TYPE_ARRAY goto return_0 ; e.g. (void *)"hello"
if *1from == *1to goto return_0 ; casting from type to same type
if *1from == TYPE_POINTER goto return_0 ; no need to do anything
; cast float/double to integer
@@ -3001,7 +3001,7 @@ function generate_code
; program header 3 (rwdata)
emit_dword(1) ; loadable segment
- emit_dword(6) ; read/write
+ emit_dword(7) ; read/write/execute (this needs to be executable for `syscall` to be implementable)
emit_qword(RWDATA_ADDR) ; offset in file
emit_qword(RWDATA_ADDR) ; virtual address
emit_qword(0) ; physical address
diff --git a/05/constants.b b/05/constants.b
index 7bcc2aa..c4c4676 100644
--- a/05/constants.b
+++ b/05/constants.b
@@ -536,6 +536,9 @@
:str_comment_end
string */
byte 0
+:str_one_line_comment
+ string //
+ byte 0
:str_lshift_eq
string <<=
byte 0
diff --git a/05/main.c b/05/main.c
index 6c19317..fc4b036 100644
--- a/05/main.c
+++ b/05/main.c
@@ -1,49 +1,50 @@
-typedef unsigned long va_list;
-#define va_start(list, arg) ((list) = (unsigned long)&arg)
-#define va_arg(list, type) (*((type *)(list += ((sizeof(type) + 7) & 0xfffffffffffffff8))))
-#define va_end(list)
+static unsigned char __syscall_data[] = {
+ // mov rax, [rsp+24]
+ 0x48, 0x8b, 0x84, 0x24, 24, 0, 0, 0,
+ // mov rdi, rax
+ 0x48, 0x89, 0xc7,
+ // mov rax, [rsp+32]
+ 0x48, 0x8b, 0x84, 0x24, 32, 0, 0, 0,
+ // mov rsi, rax
+ 0x48, 0x89, 0xc6,
+ // mov rax, [rsp+40]
+ 0x48, 0x8b, 0x84, 0x24, 40, 0, 0, 0,
+ // mov rdx, rax
+ 0x48, 0x89, 0xc2,
+ // mov rax, [rsp+48]
+ 0x48, 0x8b, 0x84, 0x24, 48, 0, 0, 0,
+ // mov r10, rax
+ 0x49, 0x89, 0xc2,
+ // mov rax, [rsp+56]
+ 0x48, 0x8b, 0x84, 0x24, 56, 0, 0, 0,
+ // mov r8, rax
+ 0x49, 0x89, 0xc0,
+ // mov rax, [rsp+64]
+ 0x48, 0x8b, 0x84, 0x24, 64, 0, 0, 0,
+ // mov r9, rax
+ 0x49, 0x89, 0xc1,
+ // mov rax, [rsp+16]
+ 0x48, 0x8b, 0x84, 0x24, 16, 0, 0, 0,
+ // syscall
+ 0x0f, 0x05,
+ // mov [rsp+8], rax
+ 0x48, 0x89, 0x84, 0x24, 8, 0, 0, 0,
+ // ret
+ 0xc3
+};
-int sum(int n, ...) {
- va_list args;
- int i;
- int total = 0;
- va_start(args, n);
- for (i = 0; i < n; ++i) {
- total += va_arg(args, int);
- }
- return total;
-}
-
-long factorial(long x) {
- if (x == 0) {
- return 1;
- } else {
- return x * factorial(x-1);
- }
-}
+#define __syscall(no, arg1, arg2, arg3, arg4, arg5, arg6)\
+ (((unsigned long (*)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long))__syscall_data)\
+ (no, arg1, arg2, arg3, arg4, arg5, arg6))
-long fibonacci(long x) {
- return x > 0 ?
- x > 1 ?
- fibonacci(x-1) + fibonacci(x-2)
- : 1
- : 0;
-}
-
-long gcd(long a, long b) {
- while (a != 0) {
- long temp = a;
- a = b % a;
- b = temp;
- }
- return b;
-}
+typedef unsigned long size_t;
-int f() {
- lb: goto lb;
+long write(int fd, void *buf, size_t count) {
+ __syscall(1, fd, buf, count, 0, 0, 0);
}
-int main(int argc, char **argv) {
- return sum(3, -100, 200, -300);
+int main(int argc, char **argv) {
+ write(1, "Hello, world!\n", 14);
+ return 0;
}
diff --git a/05/parse.b b/05/parse.b
index 52c8d4a..4373680 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -323,7 +323,9 @@ function parse_toplevel_declaration
ident_list_add(functions_required_stack_space, f_name, curr_function_stack_space)
- ;print_statement(out0)
+ ; ENABLE/DISABLE PARSING DEBUG OUTPUT:
+ print_statement(out0)
+
goto parse_tld_ret
:function_no_param_name
diff --git a/05/preprocess.b b/05/preprocess.b
index 9a7dd5c..2a94119 100644
--- a/05/preprocess.b
+++ b/05/preprocess.b
@@ -88,6 +88,8 @@ function split_into_preprocessing_tokens
if b != 0 goto pptoken_number
b = isalpha_or_underscore(c)
if b != 0 goto pptoken_identifier
+ b = str_startswith(in, .str_one_line_comment)
+ if b != 0 goto pptoken_one_line_comment
b = str_startswith(in, .str_comment_start)
if b != 0 goto pptoken_comment
; now we check for all the various operators and symbols in C
@@ -169,6 +171,10 @@ function split_into_preprocessing_tokens
; " each non-white-space character that cannot be one of the above"
goto pptoken_single_character
+ :pptoken_one_line_comment
+ ; skip over comment
+ in = memchr(in, 10)
+ goto pptokens_loop
:pptoken_comment
; emit a space ("Each comment is replaced by one space character.")
*1out = 32
diff --git a/05/stdarg.h b/05/stdarg.h
new file mode 100644
index 0000000..68fcd8e
--- /dev/null
+++ b/05/stdarg.h
@@ -0,0 +1,4 @@
+typedef unsigned long va_list;
+#define va_start(list, arg) ((list) = (unsigned long)&arg)
+#define va_arg(list, type) (*((type *)(list += ((sizeof(type) + 7) & 0xfffffffffffffff8))))
+#define va_end(list)
diff --git a/README.md b/README.md
index bc55a8b..ec85c7e 100644
--- a/README.md
+++ b/README.md
@@ -217,6 +217,11 @@ ax bx cx dx sp bp si di
│ syscall │ 0f 05 │ execute a system call │
│ nop │ 90 │ do nothing │
└──────────────────────┴───────────────────┴────────────────────────────────────────┘
+
+SYSCALLS
+Arguments are passed in
+ rdi, rsi, rdx, r10, r8, r9
+The return value is placed in rax.
```
More will be added in the future as needed.