Vous êtes sur la page 1sur 6

Steamer16 CPU and Assembly Language Reference Programming model: Steamer16 consists of a program counter (PC) and a 3-deep

evaluation stac . All instructions except "lit," operate on data already on the stac . PC is cleared on reset. Stac entries are undefined until loaded using "lit," instructions. There is also an instruction register which is not programmer-visible. There is no program status word. Instruction encoding: The PC addresses instruction pac ets and inline data, not individual instructions. Five 3-bit instruction "slots" are pac ed left-justified into each 16-bit instruction pac et with the lsb a don't care. The most significant slot in a pac et is executed first. All instructions execute identically in any slot. Inline data to satisfy any "lit," instructions follows the pac et itself. Steamer16 is a true "zero-operand" stac machine. Steamer stac diagrams: Stac diagrams are used to describe instruction behavior by showing the arguments and results on the stac in a concise notation. The arguments are on the left-hand side of the "--" before/after separator, the results are on the right. The argument and result lists show all three entries. The symbols x, y, and z denote irrelevant arguments and the original values of any surviving stac entries. Instruction descriptions and opcode assignments: NOP, {0} lit, {1} @, !, +, {2} {3} {4} ( x y z -- x y z) ( x y z -- y z data) PC++ ( x y addr -- x y data) ( x data addr -- x x x) ( x n1 n2 -- x x n1+n2) ( x n1 n2 -- x x n1&n2) ( x n1 n2 -- x x n1^n2) ( x flg addr -- x x x) no operation push data at PC, increment PC fetch data from addr store data to addr add 2ND to TOP and 2ND to TOP exclusive-or 2ND to TOP if flg equals 0 then jump to addr else continue

AND, {5} XOR, {6} zgo, {7}

Instruction timing: An instruction fetch cycle is required to load the instruction register with the pac et of 5 instructions currently addressed by the PC. The instructions contained in the pac et execute in 1 cycle each. Pac ets are fetched and executed in 6 cycles during straight-ahead execution for an average of 1.2 cycles per instruction.

As each instruction is consumed, a "NOP," is shifted into the instruction register from the right. When the remainder of a pac et consists entirely of "NOP,"s or "zgo," ta es a jump the current pac et is aborted and another instruction fetch cycle follows immediately. Depending on the code mix, a pac et may ta e anywhere between 2 and 6 cycles to fetch and execute. "NOP," padding is automatically performed by the assembler whenever a label or implicit return address is encountered in the source code. This is necessary because all labels refer to cell-aligned opcode pac ets or data, not individual instructions. Overall execution timing remains deterministic, but requires careful analysis to predict. STASM directives, utilities, and syntax: STASM was written in Forth and uses an RPN syntax except when strings are used as arguments. STASM's Forth stac is commonly used to evaluate an operand for an assembler statement. Macros are defined using standard Forth colon definitions. All of the primitives in the assembler are available for building new functions. STASM and its Forth foundation are case sensitive. Uppercase is the norm for opcode and macro names, although lowercase forms may exist for infrequently used primitive invocations. By convention, all code generating opcode mnemonics and macro names end with a comma. This is in eeping with the traditional Forth words "," and "C," and emphasizes the fact that sequential entries to memory are being performed. Naming conflicts are also avoided (eg. "AND" vs. "AND,"). RPNexpression LIT, ( x y z -- y z n)

Assemble a "lit," and an inline word popped from the Forth stac . ZGO, label ( x y flg -- y y y)

Assemble a "lit," the value of label inline, then a "zgo,". $ Push the pending pac et's location (PKTPTR) to the Forth stac . Note that another assembly pointer (OBJPTR) is also required by the internal assembler logic to separately trac the location of inline data to satisfy any "lit," instructions in the pending pac et. See STASM.4TH. RPNexpression ORG If the pending pac et is not empty then flush it to the object image at PKTPTR. Pop the Forth stac into PKTPTR and let OBJPTR = PKTPTR + 1. Fill the new pending pac et with "NOP,"s. ALIGN ORG past the pending pac et's location and inline words, if any. An explicit ALIGN must be present on the last line in the top-level sourcefile in order to ensure a complete object image. ALIGN may be

thought of as an END statement in this case. :: label ALIGN pending pac et and define label as a constant equal to the current assembly location. When label is later executed, the location is pushed to the Forth stac . RPNexpression W, ALIGN pending pac et and assemble an inline word popped from the Forth stac . ", string" ALIGN pending pac et and assemble inline string. Little-endian byte pac ing is used to form words from sequential ASCII characters, i.e. the 0th and any other even subscript characters map to the low half of each word and any odd subscript characters map to the high half. Strings are null-padded in the high byte of the last word if the number of characters is odd. If the number of characters is even then 1 trailing word of 0 is appended. The " delimiter terminates the string in the source, but is not placed in the object image. ?LBL symbol During pass 0, suppress the unresolved symbol abort and push a dummy value to the Forth stac . In pass 1, push the final value: unresolved or non-constant symbols cause respective aborts. RPNexpression RPNexpression DCL name Used to declare a label and advance the location counter for uninitialized data. Prior to execution of DCL the Forth stac holds the current location next on stac and the number of cells of memory to reserve on top of stac . When DCL executes, name is created as a constant and top and next are added, leaving the sum. An initial base address may be sequentially incremented through a series of declarations. The residual top of stac must be DROPped at the end of the series, normally by invo ing the DCL-CHECK directive. See the file ARF.MAP for an example. RPNexpression RPNexpression DCL-CHECK Used to compare a precalculated location counter value with the actual. An abort occurs if they are not equal. This is to facilitate compile-time error chec ing in conjunction with the the DCL directive. See ARF.MAP. RPNexpression ASM filename Perform the assembly pass specified by RPNexpression. Pass 0 is performed first in order to resolve forward references. Pass 1 is the final pass and requires that all symbols be defined, else an abort will occur. Any

nonzero value suffices to establish pass 1 behaviour. The filename must be the last text on the source line. LOAD filename Appropriate for including code fragments. Executes in both passes. The filename must be the last text on the source line. INCLUDE filename Appropriate for including constant and macro definitions. Executes in pass 0 only. The filename must be the last text on the source line. SAVEOBJ filename Save the object image from 0 to $ to dis . Little-endian byte order is used to transfer the cells. The filename must be the last text on the source line. GETOBJ filename Load object image from dis . Little-endian byte order is used to transfer the cells. The assembly location pointers (PKTPTR and OBJPTR) are reloaded as if the equivalent source stream was just assembled. The filename must be the last text on the source line. .BIN Dump the object image from 0 to $ to the console, displayed as words in the current BASE. .BIN8 Dump the object image from 0 to $ to the console, displayed as logical right-shifted words in octal. This facilitates human disassembly of the object image, however literal data is subject to the same reformatting. BASE is preserved. Steamer16 programming strategies: A 3-deep stac suffices to compute any RPN expression. Running out of room on the stac and/or destruction of a ey datum is avoided by operating on further data as soon as it is present (eg. "x n n + n +" preserves x but "x n n n + +" does not). Duplicate and intermediate results typically must be buffered in memory. Given a result on top of the evaluation stac , it is always possible to compute a memory address to write the result to without destroying it. Since Steamer16 lac s a memory stac pointer and call and return instructions, it is necessary to synthesize such niceties. A strategy I call ArF has proven useful. ArF defines:

See the file ARF.MAC for the standard ArF macro definitions. An ArF contract has 2 forms: 1) machine stac : :: LABEL ( arg1|x arg1|y arg1|z -- result1 result1 result1) ( comment)

The "GO," "ZGO," "()," "(())," and "<()>," macros allow passing a single argument to a procedure, in fact 3 copies are always available. The argument list should give descriptive names to the pertinent copy or copies and flag don't care copies with the names x, y, or z. The "ZRET," and "RET," macros correspondingly allow returning a single result from a procedure. The result list should contain all 3 copies in eeping with normal practice of documenting opcode and macro behavior. This method offers the maximum runtime performance and should be used whenever the number of arguments and the number of results both are <= 1. The stac frame in memory is used to hold the return address per method 2 below. A thoughtful programmer can achieve the best possible code using this method. See TIMER.FRG for examples.

:: LABEL

( arg1 .. argN : result1 .. resultN) ( comment) ( local1 .. localN) if applicable

The contract describes the structure of the stac frame within LABEL's context. Prior to ma ing a call, the parent sets X to point just above it's own frame, thereby protecting it from the child; then the arguments in the contract are initialized. The arguments include the return address (arg0), which is not explicit in the ArF contract notation. The child returns by jumping to the address in arg0, pointed to by X. The list of arguments is ended by the ":" in the contract. All arguments, results, and locals are understood to be 16-bit words in the absence of the traditional Forth "d" or "." notation. Little-endianess is mandated by convention, i.e. increasing indices to the actual 16-bit cells are associated with the more-significant cells. This method costs a certain amount of performance but relieves the programmer of the meticulous coding effort involved in method 1. Note that the arguments are not destroyed by procedures; the results are appended to the arguments. Their order within the frame is shown to the right of the ":" in the first line of the contract. If locals are used, the second line of the contract notation summarizes them and helps the programmer eep trac of their correct frame indices. The stac frame is preserved over procedure boundaries provided that X is made to point past it when a call is made. It is solely the calling parent's responsibility to manage X, the frame pointer.

2) multiple arguments and/or multiple results on the stac

1) 2) 3) 4) 5) 6)

a set of volatile scratchpad static variables (T0..TF) a frame pointer implemented as a static variable (X) macros to manipulate X and index into the frame it points to a stac frame structure (ret@, args, results, locals) a consistent re-entrancy strategy a contract notation similar to Forth stac diagrams

frame:

No procedure shall: 1) 2) 3) 4) 5) use negative indices to the passed X alter X to a value below what was passed otherwise access frame memory below passed X return with X clobbered alter the return address

Negative indices can be useful when one procedure calls another. Since X points to the child's frame on return, i.e. at a higher address than parent's frame, the child's frame may be addressed with positive indices and the parent's frame with negative indices, provided that the above restrictions are observed. A procedure has the option of using predefined static scratchpads or locals physically above the contracted results. The static scratchpads are volatile over procedure boundaries but are accessed faster than locals and are primarily useful for leaf procedures, i.e. procedures which ma e no further calls. Unli e Forth, no stac reordering operators are required. All data is randomly addressed by static address or frame index.

The hidden DUP that frequently occurs in code sequences can be used to good advantage in writing optimal code.

Unli e C, the stac results.

frame is used to both pass arguments and return

Vous aimerez peut-être aussi