FAST Forth Native-Language Embedded Computers
FAST Forth Native-Language Embedded Computers
FAST Forth Native-Language Embedded Computers
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