From: rich <rich>
Date: Sat, 29 Sep 2007 22:12:07 +0000 (+0000)
Subject: Linux system calls added and SYSEXIT removed.
X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=7bd36863d6d71c4e4f94ba745d37b21f47e2ea9c;p=rrq%2Fjonesforth.git

Linux system calls added and SYSEXIT removed.
---

diff --git a/jonesforth.S b/jonesforth.S
index d0e933e..624eba4 100644
--- a/jonesforth.S
+++ b/jonesforth.S
@@ -1,7 +1,7 @@
 /*	A sometimes minimal FORTH compiler and tutorial for Linux / i386 systems. -*- asm -*-
 	By Richard W.M. Jones <rich@annexia.org> http://annexia.org/forth
 	This is PUBLIC DOMAIN (see public domain release statement below).
-	$Id: jonesforth.S,v 1.39 2007-09-29 16:05:10 rich Exp $
+	$Id: jonesforth.S,v 1.40 2007-09-29 22:12:07 rich Exp $
 
 	gcc -m32 -nostdlib -static -Wl,-Ttext,0 -o jonesforth jonesforth.S
 */
@@ -1119,7 +1119,7 @@ var_\name :
 */
 	defvar "STATE",5,,STATE
 	defvar "HERE",4,,HERE,user_defs_start
-	defvar "LATEST",6,,LATEST,name_SYSEXIT // SYSEXIT must be last in built-in dictionary
+	defvar "LATEST",6,,LATEST,name_SYSCALL3 // SYSCALL3 must be last in built-in dictionary
 	defvar "_X",2,,TX
 	defvar "_Y",2,,TY
 	defvar "_Z",2,,TZ
@@ -1140,8 +1140,13 @@ var_\name :
 	F_IMMED		The IMMEDIATE flag's actual value.
 	F_HIDDEN	The HIDDEN flag's actual value.
 	F_LENMASK	The length mask in the flags/len byte.
+
+	SYS_*		and the numeric codes of various Linux syscalls (from <asm/unistd.h>)
 */
 
+//#include <asm-i386/unistd.h>	// you might need this instead
+#include <asm/unistd.h>
+
 	.macro defconst name, namelen, flags=0, label, value
 	defcode \name,\namelen,\flags,\label
 	push $\value
@@ -1155,6 +1160,13 @@ var_\name :
 	defconst "F_HIDDEN",8,,__F_HIDDEN,F_HIDDEN
 	defconst "F_LENMASK",9,,__F_LENMASK,F_LENMASK
 
+	defconst "SYS_EXIT",8,,SYS_EXIT,__NR_exit
+	defconst "SYS_OPEN",8,,SYS_OPEN,__NR_open
+	defconst "SYS_CLOSE",9,,SYS_CLOSE,__NR_close
+	defconst "SYS_READ",8,,SYS_READ,__NR_read
+	defconst "SYS_WRITE",9,,SYS_WRITE,__NR_write
+	defconst "SYS_CREAT",9,,SYS_CREAT,__NR_creat
+
 /*
 	RETURN STACK ----------------------------------------------------------------------
 
@@ -1226,8 +1238,6 @@ var_\name :
 	exits the program, which is why when you hit ^D the FORTH system cleanly exits.
 */
 
-#include <asm-i386/unistd.h>
-
 	defcode "KEY",3,,KEY
 	call _KEY
 	push %eax		// push return value on stack
@@ -1970,7 +1980,6 @@ _COMMA:
 	// COLD must not return (ie. must not call EXIT).
 	defword "COLD",4,,COLD
 	.int INTERPRETER	// call the interpreter loop (never returns)
-	.int LIT,1,SYSEXIT	// hmmm, but in case it does, exit(1).
 
 /* This interpreter is pretty simple, but remember that in FORTH you can always override
  * it later with a more powerful one!
@@ -2044,11 +2053,12 @@ interpret_is_lit:
 	CHAR puts the ASCII code of the first character of the following word on the stack.  For example
 	CHAR A puts 65 on the stack.
 
-	SYSEXIT exits the process using Linux exit syscall.
+	SYSCALL3 makes a standard Linux system call.  (See <asm/unistd.h> for a list of system call
+	numbers).  This is the form to use when the function takes up to three parameters.
 
-	In this FORTH, SYSEXIT must be the last word in the built-in (assembler) dictionary because we
+	In this FORTH, SYSCALL3 must be the last word in the built-in (assembler) dictionary because we
 	initialise the LATEST variable to point to it.  This means that if you want to extend the assembler
-	part, you must put new words before SYSEXIT, or else change how LATEST is initialised.
+	part, you must put new words before SYSCALL3, or else change how LATEST is initialised.
 */
 
 	defcode "CHAR",4,,CHAR
@@ -2058,11 +2068,14 @@ interpret_is_lit:
 	push %eax		// Push it onto the stack.
 	NEXT
 
-	// NB: SYSEXIT must be the last entry in the built-in dictionary.
-	defcode SYSEXIT,7,,SYSEXIT
-	pop %ebx
-	mov $__NR_exit,%eax
+	defcode "SYSCALL3",8,,SYSCALL3
+	pop %eax		// System call number (see <asm/unistd.h>)
+	pop %ebx		// First parameter.
+	pop %ecx		// Second parameter
+	pop %edx		// Third parameter
 	int $0x80
+	push %eax		// Result (negative for -errno)
+	NEXT
 
 /*
 	START OF FORTH CODE ----------------------------------------------------------------------