27.01.2015 Views

FAST Forth Native-Language Embedded Computers

FAST Forth Native-Language Embedded Computers

FAST Forth Native-Language Embedded Computers

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

MOV<br />

MOV<br />

EBX, offset v16<br />

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 contents<br />

are accessed, then consumed<br />

by the following word.<br />

For example, the sequence vl<br />

@ + might generate the following<br />

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 possible<br />

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 generated<br />

code could take advantage<br />

of the indexed addressing mode<br />

to allow otherwise-separate instructions<br />

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]<br />

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 perform<br />

computations involving<br />

literals during code generation.<br />

For example, the word sequence<br />

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 immediately<br />

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!