X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=jonesforth.S;h=c885150b0a9348812e337afaefe2b5d8e773613a;hb=abcbc5d578daa147d957f9e3c5874690ae779328;hp=d0e933ea1ff94a3e8174e1011fcf8b7be9839498;hpb=2ef2442658f010bbfcaa08954fe8451432308131;p=rrq%2Fjonesforth.git diff --git a/jonesforth.S b/jonesforth.S index d0e933e..c885150 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 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.41 2007-09-29 23:11:27 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 ) */ +//#include // you might need this instead +#include + .macro defconst name, namelen, flags=0, label, value defcode \name,\namelen,\flags,\label push $\value @@ -1155,6 +1160,22 @@ 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 + + defconst "O_RDONLY",8,,__O_RDONLY,0 + defconst "O_WRONLY",8,,__O_WRONLY,1 + defconst "O_RDWR",6,,__O_RDWR,2 + defconst "O_CREAT",7,,__O_CREAT,0100 + defconst "O_EXCL",6,,__O_EXCL,0200 + defconst "O_TRUNC",7,,__O_TRUNC,01000 + defconst "O_APPEND",8,,__O_APPEND,02000 + defconst "O_NONBLOCK",10,,__O_NONBLOCK,04000 + /* RETURN STACK ---------------------------------------------------------------------- @@ -1226,8 +1247,6 @@ var_\name : exits the program, which is why when you hit ^D the FORTH system cleanly exits. */ -#include - defcode "KEY",3,,KEY call _KEY push %eax // push return value on stack @@ -1970,7 +1989,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 +2062,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 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 +2077,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 ) + 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 ----------------------------------------------------------------------