| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#131
| |||
| |||
| Somebody asked (further back):- >> Overall, Fortran seems to have most of the stuff you need. But... Will >> you write hardware drivers in Fortran? I don't think so. Will you >> write network applications Fortran? I don't think so. Will you write >> text processing software in Fortran? I don't think so. Will you write >> a GUI library in Fortran? I don't think so. This is just a few >> examples. Is it possible to do all those things in Fortran? I wrote a hardware driver for RS232c ports for equipment control, I still use commercially - in Fortran F77. I wrote a network processing application (message switching to use mainframes as if local, between offices on three continents, for a large Oil company) - in Fortran IV. I still sell my text processing software written in Fortran, (first F77 then F90 for Windows). I wrote a TUI (sorry not GUI) library in F77, which then calls API's or DOS services. I also wrote a very general sort/merge program in F77, just because I wanted to only support the formats of the binary representations of the types of variables used by Fortran, since the data files would most probably use these formats only. As I have said here over the years, I don't know of any kind of problem I can't resolve, (supposing there is a known method), - in Fortran. And suprisingly, to a certain extent, the LESS the resources you have, the more elegant is the solution discovered for doing the job (maybe not as fast as alternatives with more resources, but simpler). |
|
#132
| |||
| |||
| <mostly OT> On Sat, 06 Sep 2008 22:36:33 -0800, glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote: > David Thompson wrote: > (snip, I wrote) > > >>I don't understand this one. C pretty much requires > >>the caller to pop the stack. (Varargs routines allow > >>a variable number of arguments.) Fortran allows > >>the callee to pop the stack. Using a special form > >>of RET in the 8086 instruction set, it takes one > >>less instruction. Most now use the C convention, though. > > > Although standard C requires that vararg routines be declared > > specifically (with a prototype using ellipsis "...") precisely so that > > they _can_ use a different calling mechanism -- and I have used a > > system where they do, so that the non-vararg case can conform to that > > machine's normal (multilanguage, fixed-frame) mechanism. > > I have known that for a while, but not known of any such > implementations. Which one is different? The bytes saved using > the special RET instruction doesn't seem a big savings. > Classic Tandem^WHP^WCompaq NonStop, still emulated on successors. Memory is (16-bit) word addressed, hardware stack using register S grows UP, register L is (dedicated) frame-base register. The original/basic calling convention is: - (compute and) push actuals left to right at ++S - PCAL instruction: push caller-L, register E (bunch of flags not relevant here), and caller's (incremented) PC; then set L to resulting S, and PC to the callee entry address (actually from a dispatch table, but that part's not relevant here) Callee prolog allocates locals by increasing S above L. (In the common case of fixed <=255 words, this is single insn ADDS const.) It then uses builtin modes to address formals as (L-3:31) and locals as (L+1:127) (even when it allocates temp space using S). For routines with lots of formals, or locals, which both C and Fortran allow, costlier insn sequences are needed outside those ranges, but these tend to be rare. Large locals -- by 16-bit standards -- can use a hidden pointer in that L+ range pointing to space further up the frame (or on NS2+ in 32-bit memory). Large arguments are usually passed by reference, so that L- is only a pointer to elsewhere. Epilog is one insn EXIT nn: drop S to (callee) L, pop caller-PC (back) into PC, pop most of E (details irrelevant here), pop caller-L back into L, and decrease S by a constant which is set to the (fixed) size of actuals pushed. For the rare case of formals exceeding the range of nn, caller cleans the remainder. OS calls use the same convention, but a slightly different insn which validates access is permitted to the callee and turns on privileged state for the callee if appropriate. The caller's privilege state is among the bits in pushed-E, and restored by EXIT -- but only if returning from a privileged/OS routine, so user code can't cheat. This allows OS calls to be declared, and compiled, as ordinary calls. The TNS object-file format is the same for linker input and output, a somewhat unusual choice (which as you have noted in other contexts is also done by OS/360 LKED), so after linking OS calls simply remain as unresolved. When a (purportedly) complete program file is first run, unresolved calls are snapped to OS entrypoints; if no match is found, the parent process gets a warning and can decide whether to continue; if it does continue, the unmatched calls are snapped as debugger calls, and if reached during execution enter the debugger (which itself is created on-demand) (except certain cases where debugging is prohibited for security, then executing such a call just dies). TNS also has its own idea of 'variable' (actually with two variants) which is completely unlike the C concept and <topical!> more like F90's OPTIONAL. Such a routine still declares its full list of formals with complete types, or at least sufficiently complete to define a fixed layout in the Lminus area. But space is also reserved for a bitmask, which each call site pushes, to specify which arguments are present/missing. The mechanism works equally for all arguments, but in practice most routines that use it put their always-required (or nearly-always) arguments to the left and their often-omitted to the right. It should be apparent that this still works with the same insns and addressing as above with only minor modification. C varargs, however, can provide from each call site different number and types/sizes of arguments. So they are pushed right to left, ending with the fixed arg(s) (C requires at least one), and callee accesses the varargs (all necessarily in memory) with a downward scanning pointer; callee EXIT cleans only the fixargs, and caller the varargs. - formerly david.thompson1 || achar(64) || worldnet.att.net |
|
#133
| |||
| |||
| glen herrmannsfeldt wrote: > David Thompson wrote: > (snip, I wrote) > >>> I don't understand this one. C pretty much requires >>> the caller to pop the stack. (Varargs routines allow >>> a variable number of arguments.) Fortran allows >>> the callee to pop the stack. Using a special form >>> of RET in the 8086 instruction set, it takes one >>> less instruction. Most now use the C convention, though. > >> Although standard C requires that vararg routines be declared >> specifically (with a prototype using ellipsis "...") precisely so that >> they _can_ use a different calling mechanism -- and I have used a >> system where they do, so that the non-vararg case can conform to that >> machine's normal (multilanguage, fixed-frame) mechanism. > > I have known that for a while, but not known of any such > implementations. Which one is different? The bytes saved using > the special RET instruction doesn't seem a big savings. Windows stdcall vs. cdecl is an example of differences in calling conventions, where only cdecl supports varargs. In fact, the way that varargs are implemented in (normally stdcall-based) COM is by converting the extra arguments into an array (a SafeArray, I believe). |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.