first C hello world!
This commit is contained in:
parent
6acd24e315
commit
2fef698195
7 changed files with 68 additions and 47 deletions
|
@ -762,7 +762,6 @@ function generate_cast_top_of_stack
|
||||||
|
|
||||||
if *1to == TYPE_VOID goto gen_cast_to_void
|
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_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 *1to == TYPE_ARRAY goto bad_gen_cast ; cast to array
|
||||||
if *1from == TYPE_FUNCTION goto bad_gen_cast ; shouldn't happen
|
if *1from == TYPE_FUNCTION goto bad_gen_cast ; shouldn't happen
|
||||||
if *1to == 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)
|
emit_add_rsp_imm32(c)
|
||||||
return
|
return
|
||||||
:gen_cast_to_integer
|
: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 == *1to goto return_0 ; casting from type to same type
|
||||||
if *1from == TYPE_POINTER goto return_0 ; no need to do anything
|
if *1from == TYPE_POINTER goto return_0 ; no need to do anything
|
||||||
; cast float/double to integer
|
; cast float/double to integer
|
||||||
|
@ -3001,7 +3001,7 @@ function generate_code
|
||||||
|
|
||||||
; program header 3 (rwdata)
|
; program header 3 (rwdata)
|
||||||
emit_dword(1) ; loadable segment
|
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) ; offset in file
|
||||||
emit_qword(RWDATA_ADDR) ; virtual address
|
emit_qword(RWDATA_ADDR) ; virtual address
|
||||||
emit_qword(0) ; physical address
|
emit_qword(0) ; physical address
|
||||||
|
|
|
@ -536,6 +536,9 @@
|
||||||
:str_comment_end
|
:str_comment_end
|
||||||
string */
|
string */
|
||||||
byte 0
|
byte 0
|
||||||
|
:str_one_line_comment
|
||||||
|
string //
|
||||||
|
byte 0
|
||||||
:str_lshift_eq
|
:str_lshift_eq
|
||||||
string <<=
|
string <<=
|
||||||
byte 0
|
byte 0
|
||||||
|
|
83
05/main.c
83
05/main.c
|
@ -1,49 +1,50 @@
|
||||||
typedef unsigned long va_list;
|
static unsigned char __syscall_data[] = {
|
||||||
#define va_start(list, arg) ((list) = (unsigned long)&arg)
|
// mov rax, [rsp+24]
|
||||||
#define va_arg(list, type) (*((type *)(list += ((sizeof(type) + 7) & 0xfffffffffffffff8))))
|
0x48, 0x8b, 0x84, 0x24, 24, 0, 0, 0,
|
||||||
#define va_end(list)
|
// 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, ...) {
|
#define __syscall(no, arg1, arg2, arg3, arg4, arg5, arg6)\
|
||||||
va_list args;
|
(((unsigned long (*)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long))__syscall_data)\
|
||||||
int i;
|
(no, arg1, arg2, arg3, arg4, arg5, arg6))
|
||||||
int total = 0;
|
|
||||||
va_start(args, n);
|
|
||||||
for (i = 0; i < n; ++i) {
|
|
||||||
total += va_arg(args, int);
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
long factorial(long x) {
|
typedef unsigned long size_t;
|
||||||
if (x == 0) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return x * factorial(x-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long fibonacci(long x) {
|
long write(int fd, void *buf, size_t count) {
|
||||||
return x > 0 ?
|
__syscall(1, fd, buf, count, 0, 0, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int f() {
|
|
||||||
lb: goto lb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
return sum(3, -100, 200, -300);
|
write(1, "Hello, world!\n", 14);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,9 @@ function parse_toplevel_declaration
|
||||||
|
|
||||||
ident_list_add(functions_required_stack_space, f_name, curr_function_stack_space)
|
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
|
goto parse_tld_ret
|
||||||
|
|
||||||
:function_no_param_name
|
:function_no_param_name
|
||||||
|
|
|
@ -88,6 +88,8 @@ function split_into_preprocessing_tokens
|
||||||
if b != 0 goto pptoken_number
|
if b != 0 goto pptoken_number
|
||||||
b = isalpha_or_underscore(c)
|
b = isalpha_or_underscore(c)
|
||||||
if b != 0 goto pptoken_identifier
|
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)
|
b = str_startswith(in, .str_comment_start)
|
||||||
if b != 0 goto pptoken_comment
|
if b != 0 goto pptoken_comment
|
||||||
; now we check for all the various operators and symbols in C
|
; 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"
|
; " each non-white-space character that cannot be one of the above"
|
||||||
goto pptoken_single_character
|
goto pptoken_single_character
|
||||||
|
|
||||||
|
:pptoken_one_line_comment
|
||||||
|
; skip over comment
|
||||||
|
in = memchr(in, 10)
|
||||||
|
goto pptokens_loop
|
||||||
:pptoken_comment
|
:pptoken_comment
|
||||||
; emit a space ("Each comment is replaced by one space character.")
|
; emit a space ("Each comment is replaced by one space character.")
|
||||||
*1out = 32
|
*1out = 32
|
||||||
|
|
4
05/stdarg.h
Normal file
4
05/stdarg.h
Normal file
|
@ -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)
|
|
@ -217,6 +217,11 @@ ax bx cx dx sp bp si di
|
||||||
│ syscall │ 0f 05 │ execute a system call │
|
│ syscall │ 0f 05 │ execute a system call │
|
||||||
│ nop │ 90 │ do nothing │
|
│ 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.
|
More will be added in the future as needed.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue