THIS IT NOT COMPREHENSIVE DESCRIPTION! USE OFFICIAL METHODICAL FOR MORE INFO!
This guide in russian: https://github.com/Zerumi/OPD-guide-RU-
In BCOMP, plain numbers like 1
, 15
are treated as decimal not as hex!
Be careful and don't miss the 0x
prefix! Actual hex number would be: 0x15
Example:
in 15 ; this is DECIMAL! Reads literally
; from fifteenth external register (actual address is 0xF)
; that is from External Device 5 - Text Printer
; vs
in 0x15 ; reads from twenty first (21 in decimal) external register
; that is from External Device 7 - 7 segment indicator
; from status register
You can found examples of reports which we at least partially accepted by teacher in reports
folders.
BCOMP can be launched in next modes:
gui
-- default mode (graphical interface)cli
-- command line interfacedecoder
-- dump default micro-program (microcode) into terminalnightmare
-- literally nightmare, don't launch or you will get mental traumadual
-- launches bcomp in bothgui
andcli
modes simultaneously (recommended for tracing)
To launch bcomp in certain mode specify flag -Dmode=mode_name
and replace mode_name
with one of the above. Example:
java -jar -Dmode=dual bcomp-ng.jar
Assembly code can be written both in foreign text editors (like vscode or vim) and in cli
mode.
In general, assembly is written alike below:
[LABEL: ] COMMAND_MNEMONIC ARGUMENT
Note: square brackets means that this part is optional. To see full syntax look at page 51 in methodical
Labels are useful to refer to some location in memory. Read more in addressing section.
Numbers can be written as decimal (e.g. 15
) or hexadecimal (e.g. 0xF
).
Here some special commands that might come in handy:
Command | Description |
---|---|
org ADDRESS |
guides the compiler to place next value (be it a raw value or a command) into cell with address ADDRESS . Subsequent commands will be placed after ADDRESS one by one |
word 0x0000,0xffa4,0xfa |
Places specified value into memory as is. ? is equal to 0x0000 in this context 0x15 is equal to 0x0015 |
Note: you can use any case of letters you desire: 0xfA51
, 0xFF
, 0xac
are all valid.
These special commands are not represented in bcomp
memory. They are intended to assist you write assembly code
There is special label START
. It tells bcomp from where to start execution. Address, to which START
refers, is placed into IP
. This means, the program can be executed right off start of bcomp.
Here is simple example (For more advanced one look here):
org 0x04f
VAR1: word 0x45a9
START: add 0xf
sub VAR1
Here 0x45a9
will be placed in memory as is at address 0x04f
; add 0xf
at 0x050
and so on. Also 0x050
(the address with special label START
) is loaded into IP
. Thus you don't have to manually setup this.
BCOMP has additional parameter to load file with code: -Dcode=file
where file
is any valid path to existing file: foobar.asm
, ./keklol
, /home/foo/kek
are all valid.
Note: .asm
extension is optional and is not required. File can have any name that your OS accepts.
So to load some code and trace it you would type something like:
java -jar -Dmode=dual -Dcode=main.asm bcomp-ng.jar
CLI is pretty cool. Finally you can input hexadecimal numbers. Seriously, just type it:
ffae
This will set Input Register
to the value you wrote.
Then, you can type:
a
and value of Input Register
will be loaded into IP
register (analogue to press of Enter Address
button in gui
mode).
For more commands see help
.
You can also write assembly right in BCOMP:
asm
Введите текст программы. Для окончания введите END
add 0xff
sub (0xf1)
end
Launch BCOMP in dual
mode and load your .asm
file like described in this section.
To see nice trace table in your terminal press continue
button in GUI. You will see how neat lines appear in your terminal.
After program has been executed completely:
- Copy trace table from terminal.
- Paste it into raw text file e.g.
text.txt
. - Replace all spaces (
,
). - Rename file to something like
text.csv
. - Open the file with Libreoffice Calc or another sheet processing program
- Copy table from Calc to Libreoffice Writer or another program you are writing report in
- Format header of the table
When you see something like this 2EF5
the second letter (E
here) is responsible for addressing mode. Look at the table below (L
stand for Label
)
Hex code | Name | Notation | Example | Description |
---|---|---|---|---|
0x0-0x7 | Absolute | add $L add ADDR |
add $VAR1 add 0xf |
Add number from memory cell with address 0xf or from $VAR1 label |
0xE | Direct relative | add L |
add VAR1 4EFE |
Only labels are supported! IP + 1 + OFFSET . Notice, that IP point to next command. So that is where + 1 comes from. Offset can be positive and negative. Something like 0x80 , 0xfe is negative. Let's assume that 4EFE (add ) have address 0x010 . Therefore it points to address right before 4EFE (0xFE is negative = -2 ) i.e. 0x009 . 4EFF point to itself |
0x8 | Indirect relative | add (L) |
add (VAR1) |
Works like pointers in C/C++. It's like saying: Hey, look in this box. Here you find paper which tells you where exactly the thing is. add --(Direct relative)--> VAR1 --(Absolute)--> value MORE DETAILS BELOW TABLE |
0xA | Indirect autoIncrement | add (L)+ |
add (VAR1)+ |
Same like above but after absolute address has been loaded into register, address itself in memory cell is incremented. AD = VAR1 VAR1 += 1 VAR1 is a pointer. So pointer is modified. Yes, we are crazy here, we do pointer arithmetics |
0xB | Indirect autoDecrement | add -(L) |
add -(VAR1) |
VAR1 -= 1 AD = VAR1 Again, pointer is modified, NOT value it points to |
0xC | Displacement SP | add &N add (sp + N) |
add &0x4a add (sp + 0x4a) |
TODO |
0xF | Direct Load | add #N |
add #0xff |
Load specified value into DR . Then a command may decide what to do with operand, e.g. load it into AC or do something else. Only one byte value can be set with direct load. The sign of value bit-extends i.e. 0xfe becomes 0xfffe and 0x7f becomes 0x007f |
Note: more information in methodical page 22 and page 32
Let's consider example:
org 0x10 ; this command is optional because bcomp places program into this address by default
POINTER: word 0x15 ; absolute address of operand
LD (POINTER)
org 0x15
word 0x45a9 ; actual operand
Here, LD (POINTER)
LD will look like this in memory: 0xA8FE
.
A
means that the command is LD
, 8
denotes that addressing mode is indirect relative
and FE
is offset. Since offsets are represented in two's complement form, FE
means (-2).
As you remember, IP
is already incremented so at this time it points to 0x11 + 0x1 = 0x12
.
Therefore LD will look for content at address 0x12 - 0x2 = 0x10
. Content of that cell will be interpreted as absolute address 0x15
of where to search for operand. So the value at address 0x15
(which is 0x45A9
in the example) will be loaded into Accumulator register.
Note: [0, 2] means from 0 to 2 inclusive on both ends
Stage | Amount of memory accesses |
---|---|
instruction fetch | 1 |
address fetch | [0, 2] |
operand fetch | 1 |
execution | [0, 1] |
interrupt | TODO |
Note: operand fetch is skipped for commands, which have 1
in their 14 bit:
0100 0000 0000 0000
here 14
bit is highlighted and set to 1
P.S. Pull requests are welcome