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 *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
|
||||
|
|
|
@ -536,6 +536,9 @@
|
|||
:str_comment_end
|
||||
string */
|
||||
byte 0
|
||||
:str_one_line_comment
|
||||
string //
|
||||
byte 0
|
||||
:str_lshift_eq
|
||||
string <<=
|
||||
byte 0
|
||||
|
|
89
05/main.c
89
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;
|
||||
#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))
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
long write(int fd, void *buf, size_t count) {
|
||||
__syscall(1, fd, buf, count, 0, 0, 0);
|
||||
}
|
||||
|
||||
long factorial(long x) {
|
||||
if (x == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return x * factorial(x-1);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int f() {
|
||||
lb: goto lb;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
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 │
|
||||
│ 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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue