projects
/
rrq
/
jonesforth.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
456b467
)
Linux system calls added and SYSEXIT removed.
author
rich
<rich>
Sat, 29 Sep 2007 22:12:07 +0000
(22:12 +0000)
committer
rich
<rich>
Sat, 29 Sep 2007 22:12:07 +0000
(22:12 +0000)
jonesforth.S
patch
|
blob
|
history
diff --git
a/jonesforth.S
b/jonesforth.S
index d0e933ea1ff94a3e8174e1011fcf8b7be9839498..624eba46460c14f1e560a7eaeaa5072afc854a9c 100644
(file)
--- 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).
/* 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_SYS
EXIT // SYSEXIT
must be last in built-in dictionary
+ defvar "LATEST",6,,LATEST,name_SYS
CALL3 // 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, SYS
EXIT
must be the last word in the built-in (assembler) dictionary because we
+ In this FORTH, SYS
CALL3
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 SYS
EXIT
, or else change how LATEST is initialised.
+ part, you must put new words before SYS
CALL3
, 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 ----------------------------------------------------------------------