summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Makefile15
-rw-r--r--main.s10
-rw-r--r--sys.s69
-rw-r--r--syscall.awk12
5 files changed, 110 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..68db9ac
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+syscall.s
+hello
+*.o
+*~
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..69beadf
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+PROGNAME=$(shell pwd | xargs basename)
+
+$(PROGNAME): main.o
+ ld -o $@ $<
+
+%.o: %.s syscall.s
+ as -o $@ $<
+
+syscall.s: /usr/include/asm/unistd_64.h
+ @echo create $@ from $<
+ @awk -f syscall.awk $< > $@
+
+clean:
+ @echo cleaning...
+ @rm -f syscall.s *~ *.o core*
diff --git a/main.s b/main.s
new file mode 100644
index 0000000..aa1f293
--- /dev/null
+++ b/main.s
@@ -0,0 +1,10 @@
+.include "sys.s"
+
+.globl _start
+_start:
+ sys write, $STDOUT, $msg, $len
+ sys exit, $0
+
+.data
+msg: .ascii "Hello, World!\n"
+len = .-msg
diff --git a/sys.s b/sys.s
new file mode 100644
index 0000000..2a76e09
--- /dev/null
+++ b/sys.s
@@ -0,0 +1,69 @@
+.ifndef __SYS__
+.set __SYS__, 1
+
+.include "syscall.s"
+
+# sys call args:
+# %rdi
+# %rsi
+# %rdx
+# %rcx
+# %r8
+# %r9
+
+.macro __putargs6 arg:req, args:vararg
+ movq \arg, %r9
+.endm
+
+.macro __putargs5 arg:req, args:vararg
+ movq \arg, %r8
+.ifnb \args
+ __putargs6 \args
+.endif
+.endm
+
+.macro __putargs4 arg:req, args:vararg
+ movq \arg, %rcx
+.ifnb \args
+ __putargs5 \args
+.endif
+.endm
+
+.macro __putargs3 arg:req, args:vararg
+ movq \arg, %rdx
+.ifnb \args
+ __putargs4 \args
+.endif
+.endm
+
+.macro __putargs2 arg:req, args:vararg
+ movq \arg, %rsi
+.ifnb \args
+ __putargs3 \args
+.endif
+.endm
+
+.macro __putargs1 arg:req, args:vararg
+ movq \arg, %rdi
+.ifnb \args
+ __putargs2 \args
+.endif
+.endm
+
+.macro sysargs args:vararg
+.ifnb \args
+ __putargs1 \args
+.endif
+.endm
+
+.macro sys func:req, args:vararg
+ sysargs \args
+ movq $__NR_\func, %rax
+ syscall
+.endm
+
+.set STDIN, 0
+.set STDOUT, 1
+.set STDERR, 2
+
+.endif
diff --git a/syscall.awk b/syscall.awk
new file mode 100644
index 0000000..521fee8
--- /dev/null
+++ b/syscall.awk
@@ -0,0 +1,12 @@
+BEGIN {
+ print ".ifndef __SYSCALL__"
+ print ".set __SYSCALL__, 1"
+ print ""
+}
+
+/#define __NR_/ { printf ".equ %s, %s\n", $2, $3 }
+
+END {
+ print ""
+ print ".endif"
+}