23.10.2013 Views

FAST Forth Native-Language Embedded Computers

FAST Forth Native-Language Embedded Computers

FAST Forth Native-Language Embedded Computers

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

MOV EBX, offset v16<br />

MOV EBX, [EBXI<br />

These instructions can be<br />

replaced by the single code<br />

instruction:<br />

MOV EBX, vl<br />

Another common situation<br />

occurs where a variable's con-<br />

tents are accessed, then con-<br />

sumed by the following word.<br />

For example, the sequence v l<br />

@ + might generate the follow-<br />

ing code without combining:<br />

MOV EBX, offset vl<br />

MOV EBX, [EBXI<br />

ADD EAX, EBX<br />

When combining is used,<br />

the above three-machine-code<br />

instructions are replaced with a<br />

single instruction:<br />

ADD EAX, vl<br />

Other combinations are pos-<br />

sible as well. For example, an<br />

index may be scaled, then added<br />

to the base address of an array<br />

of 32-bit values; the indexed<br />

element is then accessed. An<br />

example is the sequence<br />

arrayl vl @ 4* + @ (where<br />

array 1 returns the starting<br />

address of an array of 32-bit<br />

values). The resulting gener-<br />

ated code could take advantage<br />

of the indexed addressing mode<br />

to allow otherwise-separate in-<br />

structions to be combined:<br />

MOV EBX, vl<br />

MOV EBX, arrayll4*EBXl<br />

Figure Three. Code generated by swap with and without preceding drop. I<br />

state = 1 state =6 state = 1 state =6<br />

ldrop] I=]<br />

(drop generates no code itself, but it<br />

changes the stack state to 0 before<br />

swap generates its code!)<br />

It also makes sense to per-<br />

form computations involving<br />

literals during code generation.<br />

For example, the word se-<br />

quence c 1 4 * 1+ + (where c 1<br />

is defined by the phrase 30<br />

constant c 1) may generate the code instruction:<br />

ADD 121 (cl = 30, so4 * cl + 1 = 121)<br />

This also applies to address calculations, such as for the<br />

sequence arrayl 20 + @:<br />

MOV EBX, arrayl+20<br />

Another situation where combining code instructions is<br />

particularly useful occurs when a test is followed immedi-<br />

ately by a control-structure word such as i f or until. The<br />

need to generate an explicit flag is thus eliminated, and the<br />

test plus control-structure branch can often be reduced to<br />

For those of you not familiar with lnlel assembler notation, the use of offset<br />

before an address value causes the address value to be treated as a literal. If<br />

an address value is not preceded by offset, the corresponding memory<br />

location is accessed instead. However, a non-address value does not need<br />

offset to be treated as a literal.<br />

Figure Four. Illustration of the virtual offset.<br />

Initial Voffs (virtual offset) = zero<br />

new<br />

value<br />

Initial Push 2 items Pop 1 item Pop 2 items Pop 1 item Update<br />

to memor from memory from memory from memory pointer<br />

(~offs-=EY (Voffs+=.l) (Voffs +=8) (Voffs +=4) (Voff s=O)<br />

from two to four instructions. For example, the sequence =<br />

if ... then might generate the following code:<br />

MOV EBX, (ED11<br />

ADD EDI, 4<br />

CMP EAX, EBX<br />

JNE -LBL-nnn<br />

(-LBL-nnn is a compiler-generated jump label)<br />

Of course, a comparison with a literal or constant value<br />

generates even simpler code. For example, the sequence<br />

8 < if ... then might generate the following code:<br />

CMP EAX, 8<br />

JNL - LBL-nnn<br />

. . .<br />

March 1994 April 38 <strong>Forth</strong> Dimensions

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!