It's originally based on: https://gist.github.com/dockimbel/7713170
5 * 10
in BF
(Constant multiplication is optimised by the compiler)
bf/comment-start {+++++[->++++++++++<]} " ;"
yields
MVI D,10 ; Data starting at 0A00h
ADI 50 ; 5 * 10
STAX D ; Save to memory before exiting
HLT ; Exit
5 - 3
in BF
(Substraction is not yet optimised)
bf/comment-start {+++++>+++[-<->]} " ;"
yields
MVI D,10 ; Data starting at 0A00h
ADI 5 ; + 5
STAX D ; >
INX D
LDAX D
ADI 3 ; + 3
label1: NOP ; [
DCR A ; - 1
STAX D ; <
DCX D
LDAX D
DCR A ; - 1
STAX D ; >
INX D
LDAX D
CPI 0
JNZ label1 ; ]
STAX D ; Save to memory before exiting
HLT ; Exit
Many 8085 emulators / assemblers have different comment line starts, you can choose the one you need by using the /comment-start
refinement or you disable all comments by using the /no-comments
refinement. Default comment is a #
without a preceeding space. To compile a snippet for GNUSim8085 for example, you have to use ;
without a preceeding space as the comment, as follows:
bf/comment-start {... code goes here ...} ";"
On the other hand, the online interpreter sim8085 allows you to include a preceeding space, to enchant readability.
Furthermore, some emulators / assemblers interpret a number followed by a h
as a label, so only decimal addresses and numbers are used here.
Port 1, and currently only Port 1 is used as the Input / Output of the program (,
and .
in BF). The compiled program does not wait until input "is available". This behaiviour may improve in the future, but feel free to submit a PR if you want it earlier :P.
The compiler matches the BF code against a set of rules, and generates the mnemonics (You didn't expect this, did you? :P). On program execution, changes are always first performed on registers and then written to RAM on pointer move (>
and <
).
- Register
A
contains the value of the current cell. - Register
D
andE
contain the16 Bit
address of the current cell. It's set to0A00
Hex (1000
decimal) on program start.
The BF program is compiled to assembly applying some basic, naive optimisations:
- A multiplication of two constants is replaced with an
ADI
instruction [-]
, used for zeroing a cell, is replaced with a XOR of the register with itself (XRA A
)- Pointer moves below 5 get compiled to single increments of the pointer, whetever pointer moves above and including 5 get compiled to an
ADD
to safe cycles. This is done because the pointer is stored as a16 Bit
address, and an16 Bit
addition is in our case as expensive as 5 increments. E.g.:
+++ ->
...
INX D
INX D
INX D
...
++++++ ->
...
ADI D,6
...
- Similiar to that above, single increments of a cell get compiled to an
INR
, but starting from 2 increments an addition is performed (ADI
)