Linux system calls added and SYSEXIT removed.
authorrich <rich>
Sat, 29 Sep 2007 22:12:07 +0000 (22:12 +0000)
committerrich <rich>
Sat, 29 Sep 2007 22:12:07 +0000 (22:12 +0000)
jonesforth.S

index d0e933e..624eba4 100644 (file)
@@ -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).
 /*     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
 */
 
        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 "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
        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.
        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
        .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 "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 ----------------------------------------------------------------------
 
 /*
        RETURN STACK ----------------------------------------------------------------------
 
@@ -1226,8 +1238,6 @@ var_\name :
        exits the program, which is why when you hit ^D the FORTH system cleanly exits.
 */
 
        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
        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)
        // 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!
 
 /* 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.
 
        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
        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
 */
 
        defcode "CHAR",4,,CHAR
@@ -2058,11 +2068,14 @@ interpret_is_lit:
        push %eax               // Push it onto the stack.
        NEXT
 
        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
        int $0x80
+       push %eax               // Result (negative for -errno)
+       NEXT
 
 /*
        START OF FORTH CODE ----------------------------------------------------------------------
 
 /*
        START OF FORTH CODE ----------------------------------------------------------------------