From 7bd36863d6d71c4e4f94ba745d37b21f47e2ea9c Mon Sep 17 00:00:00 2001 From: rich Date: Sat, 29 Sep 2007 22:12:07 +0000 Subject: [PATCH] Linux system calls added and SYSEXIT removed. --- jonesforth.S | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) 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 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 ) */ +//#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,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 - 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 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 ) + 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 ---------------------------------------------------------------------- -- 1.8.3.1