Releases: TollyH/AssEmbly
Release 4.0.0
.NET 8 install required for the included executable.
The most recent version of the Reference Manual is also hosted at https://tollyh.github.io/AssEmbly
Additions:
- Displacement: Pointers can now be used to access relative memory addresses without needing to modify the value of the register itself. Displacement of pointers is evaluated at runtime and is written using square brackets like so:
*rg0[rg1 * 8 + 123]
. Labels and addresses can also be displaced, but only by constant values, as this displacement is done at assemble-time. TheEXTD_MPA
instruction has been added to calculate the address of a pointer without accessing memory at that address. - Pointer read sizes: Pointers can now be used to read 32-bit, 16-bit, and 8-bit numbers from memory inline using the explicit read size specifiers
D*
,W*
, andB*
. This removes the need to first callMVD
,MVW
, orMVB
, which would potentially also use up an extra register. - File system extension set: There are now instructions for performing more general file system operations, such as: directory listing, directory creation/deletion, file moving and copying, and file time getting/setting.
- Terminal extension set: There are now instructions for interacting with the terminal window. This includes operations such as: clearing the screen, setting foreground and background colours, setting/getting the position of the cursor and screen size, and playing a beep sound. There are also two new instructions and a new status flag for toggling on and off the "auto echo" behaviour of the
RCC
instruction. - A new
EXTD_SLP
instruction has been added which causes the processor to sleep for a specified number of milliseconds when executed. - The exit code of the AssEmbly process can now be specified with the new
EXTD_HLT
instruction. - New instructions have been added for querying the version and supported features of the AssEmbly processor at runtime.
%ANALYZER
directive ranges now work as expected for all assembler messages, including those depending on finalizers.- The
help
operation has been improved, with each operation now having its own help page that lists the options specific to that operation. The base help page is now much more concise. - Command line argument parsing has been overhauled to be much more efficient and consistent. New, single-character arguments denoted with a single dash have been added. Unrecognised arguments will now produce a warning.
- Operations (
assemble
,execute
, etc.) are now case-insensitive. - Hexadecimal and binary literals can now be made negative with a
-
prefix. - The assembler will now automatically define macros (
#FILE_PATH
,#FILE_NAME
, and#FOLDER_PATH
) that allow you to access the path of the file currently being assembled. This can be disabled if necessary with the--disable-file-macros
argument. - A
--full-base-opcodes
argument has been added to the assembler to force instructions in the Base Instruction Set to be assembled into their full, 3-byte form. - New assembler constants have been added which signify whether each extension set is available. There are also constants for checking whether full base opcodes are forced and whether automatically defined file path macros are enabled.
- The assembler is now aware of the path to the base file, and it will now be displayed in errors and warnings instead of a generic
base file
message. The path to the base file will now also be populated into ADI files. - The disassembler can now detect floating point and negative operands. You can disable this with the
--no-floats
and--no-signed
arguments. - A new suggestion has been added to suggest that
%NUM
is used instead of chaining 8 consecutive%DAT
directives. - Another new suggestion has been added to suggest using the inline assignment capabilities of the
CAL
andRET
instructions instead of settingrfp
/rrv
withMVQ
directly before them.
Fixes:
- Fixed an issue with float to integer conversion that caused incorrect values to be returned on some ARM platforms.
- The assembler will no longer suggest that the
:ENTRY
label is unused. - Single disassembled instructions (such as those displayed in the debugger) will no longer be missing a
0x
prefix on address literals. - Redirecting the standard input stream of the processor will no longer cause the
RCC
instruction to crash. - Warnings that depend on knowing what the previous instruction was will no longer be suppressed by state directives that insert no data.
Removals:
- Warning 0003: "Jump/Call target address points to end of file, not executable code." has been removed as it is superfluous when Warning 0002: "Jump/Call target address does not point to executable code." exists. The code Warning: 0003 will now remain unused.
Example program changes:
- All example programs have been updated to utilise features added in this update.
- A new directory listing example program has been added.
Internal changes:
- The
Processor
class now contains methods for reading and writing null-terminated UTF-8 strings in memory. - A new
CommandLineArgs
class has been added to facilitate the improvements in argument parsing added in this update. - Regular expressions now all use the
GeneratedRegex
attribute to improve performance. - The project now supports conditional compilation using C# preprocessor constants. All operations and AAP features are now entirely optional and can be omitted from the compilation.
- String resource files have been split into separate files depending on the operation they are used by. Resource files for operations that are not being compiled will be omitted.
- A new script has been added to automatically test different permutations of project compilation options.
- Methods have been added to
Program.Shared.cs
for printing errors and warnings. ReadOnlySpan
s are now created explicitly instead of using the implicit cast fromSpan
s created by the.AsSpan()
method. This contributes to a slight performance improvement.
Release 3.2.0
.NET 8 install required for the included executable.
The most recent version of the Reference Manual is also hosted at https://tollyh.github.io/AssEmbly
Additions:
- Improved macros: Improvements to the existing macro system as well as many new features, including:
- Multi-line macros that can insert multiple lines into the program wherever the macro is used.
- Macro parameters that enable the insertion of differing content with the same macro.
- Macros can now be deleted with the
%DELMACRO
directive. - Ability to disable the expansion of macros on a specific line (by prefixing the line with
!
) or in entire blocks of lines (by surrounding the lines with!>
and<!
). Macro expansion is automatically disabled for the%MACRO
and%DELMACRO
directives so that it doesn't interfere with their operation. - Macro replacement on each line is now much more consistent, with nested macros now being reliably supported.
- Errors and warnings will now display the name of the macro they were raised within, if applicable.
- Assembler variables: Added numeric variables defined with the
%DEFINE
directive that exist for the duration of assembly, which can be inserted into the program as a literal number. They can have mathematical and logical operations performed on them at assembly-time with the%VAROP
directive.- Includes predefined assembler constants, which allow the program to determine things about the assembler, such as the current address, AssEmbly version, and the enabled compatibility flags.
- Can be defined from the command line before assembly begins with the
--define=
parameter.
- Conditional assembly:
%IF
,%ELSE_IF
, and%ELSE
directives have been added which are used to only assemble blocks of code if specific conditions are met.- Can check for the existence of assembler variables as well as compare numeric values.
- Can be nested within each other.
- Code repetition:
%REPEAT
and%WHILE
assembler directives have been added that can be used to repeatedly assemble a section of source code - either a set number of times, or until a condition becomes false respectively. - Open source licensing: AssEmbly is now released under the GPLv3 open source license. The documentation is released under a similarly permissive CC BY-SA 4.0 license.
- References can now be made to literal addresses without needing a label that points there.
- The debugger will now use this syntax in the disassembled instruction view, instead of generating a dummy label name.
- The disassembler will use this syntax if it cannot insert a label definition at the desired address. This means that the disassembler will now never produce programs that cannot be re-assembled.
- The following additional directives have been added:
- A
%LABEL_OVERRIDE
directive that allows the assignment of a custom address to labels. - A
%STOP
directive that can be used to stop assembly with a guaranteed error and a custom message. - An
%ASM_ONCE
directive that prevents an imported file from being assembled multiple times, and can prevent cyclic import errors when used as the first statement in a file.
- A
- All directives now begin with a
%
sign to distinguish them from regular instructions. The old directives can still be used if the--allow-old-directives
parameter is given when running the assembler. - Warnings will now be displayed if the processor halts while there is:
- One or more allocated regions of memory that haven't been freed with
HEAP_FRE
. - A file still open that hasn't been closed with
CFL
. - An external assembly still open that hasn't been closed with
ASMX_CLA
.
- One or more allocated regions of memory that haven't been freed with
- Considerable performance improvements have been made to both the assembler and disassembler. The assembler is now ~2.8x faster than 3.1.0, and the disassembler is now ~7x faster.
- The disassembler now includes backslashes in disassembled strings, and will use the line endings of the current system.
- The disassembler will now always produce byte-perfect programs. In order to achieve this, the valid but unused operand form
0xFF, 0x00, 0x..
for the base instruction set will now be treated as data instead of as an instruction. To restore the old behaviour, use the--allow-full-base-opcodes
parameter. - Debug information files now contain a map of addresses to the line and file that they were assembled from, so that the debugger can show the source location of each statement being executed.
- Using
RCC
will no longer print the character that the user typed to the console by default. You should instead give the character toWCC
or use the--auto-echo
parameter to restore the old behaviour. - A new assembler suggestion has been added that detects label definitions that are never used.
- An
--output-expanded
parameter has been added that outputs the fully expanded source code lines assembled by the assembler for debugging purposes. This includes imported lines and expanded macros all within one file, so that you can see the lines as the assembler sees them. - New compatibility parameters have been added to: disable assembler variable expansion (
--disable-variables
- for pre-3.2 strings), and to disable escape sequences (--disable-escapes
- for pre-1.1 strings).
Fixes:
- Inserting a sole raw
0xFF
byte will no longer crash the assembler. - The assembler will no longer crash when the invalid literals
0x_
or0b_
are used. - The disassembler will now no longer crash if the program ends with a
0xFF
byte. - Command line arguments are now all consistently case-insensitive.
- Invalid ADI files will no longer be generated in the case that multiple imports start on the same address (this was only possible when importing files that insert no bytes).
- A warning is now correctly given when a negative literal is given as the second operand to the
SHL
,SHR
, andSIGN_SHR
instructions. - Warning 0015 will no longer be erroneously given if the instruction following the
%IMP
directive is not executable. - Suggestion 0011 will no longer be erroneously given for the
%ANALYZER
directive. - Warnings 0001, 0009, and 0010 will no longer be erroneously given when the last instruction in the file is a state directive.
- The processor will now throw the correct exception type when an error occurs loading an external assembly.
Example program changes:
- A new bitmap encoding example has been added, along with a QOI to BMP converter program.
- The console input example program now handles the user pressing the backspace key, and also adds a null terminator after the final typed character.
- The calculator example has been updated to use a single input buffer allocated with the memory allocation extension set.
- Many examples have been updated to utilise the new features added in this release.
- Unused labels have been removed from the file read example.
- Unnecessary
TST
instructions have been removed from multiple examples.
Internal changes:
- The
Assembler
class has been significantly refactored. Much of it is no longerstatic
and so now requires instantiation to be used. Assembly logic has been broken up across more methods to aid portability and readability.- All assembler directives are now located in a separate file within their own methods.
- The assembler now has support for getting/setting its current position. This is primarily utilised by the
%REPEAT
/%WHILE
directives.
- The disassembler has undergone major refactoring to improve performance.
- A reverse lookup dictionary is now used to map opcodes to mnemonics instead of iterating over the mnemonic to opcode map each time.
- The entire disassembly is now done in one pass, instead of the multi-pass string replacement based approach used before.
- Memory access functions in the
Processor
class have been marked withMethodImplOptions.AggressiveInlining
for a slight performance boost. - A Python script has been added to the repository for updating old AssEmbly programs to new syntax. There is also a script for converting programs written in the Whitespace esoteric language to equivalent AssEmbly programs.
- ADI files now use a
StringBuilder
during generation to improve performance. - ADI files now consistently use LF (
0xA
) line endings. - Some extension methods for
Stack<T>
operations have been implemented, such as cloning and nested copying. - The
Processor
class now has properties for checking if resources are currently open. - Applicable classes have been converted to use primary constructors.
- A new
FilePosition
struct has been created to replace storing file paths and line numbers separately. - Processor runtime errors will now cause the host AssEmbly executable to exit with a non-zero exit code.
- The project is now built for multiple different platforms.
- The repository now contains a
build.ps1
PowerShell script that can be used to build both the application and the documentation. - The printed program header will now show when a debug build is being used. Debug builds also now re-throw most exceptions in addition to replacing them with a friendly error message as release builds do.
- Case-insensitive string comparisons now use the
Equals
method instead of theToUpper
/ToLower
methods. - Additional strings have been moved to the localisable string resource file.
- The string resource file now uses spaces instead of tab characters for indentation.
- The
0xFF
full size opcode marker is now stored in a constant. - The entire assembly result is now serialised when linting, allowing the VSCode extension to highlight unassembled lines.
MnemonicComparer
is no longer contained within its own file, as it is only ever used inData.cs
.- A reverse lookup Dictionary for retrieving mnemonics from opcodes has been added.
- Many more unit t...
Release 3.1.0
.NET 8 install required for the included executable
Additions:
- Added three new assembler directives:
IBF
: Takes the raw bytes from an external file and inserts them as-is into the final programMESSAGE
: Manually emits an assembler warning with a given severity and an optional custom message (has no effect on program)DEBUG
: Prints the current state of the assembler to the console (happens at assemble-time, has no effect on program)
- Improvements to the debugger
map
command:- A new table column has been added to show the ASCII representation of the displayed bytes.
- Consecutive rows of all
00
bytes now get collapsed into a single asterisk (*
).
- Assembler warnings are now sorted by severity before being printed.
- The message printed to the console when assembly is complete now contains additional details, including:
- Final program size, both with and without header
- Compression ratio and compressed size (with the
--compress
parameter) - Time taken to assemble
- Number of lines and files assembled
- Number of errors, warnings, and suggestions
Fixes:
- The debugger
stack
command no longer incorrectly showsrso
as pointing to the top stack item when the output is limited. - The
stack
command also no longer misspells therso
register asrsp
.
Documentation Errors
- The first code example in the "Address" subsection of the "Operand Types" section should use
MVB
, notMVQ
.
Release 3.0.0
.NET 8 install required for the included executable
Additions:
- C# interoperation: An extension set for calling external .NET methods has been introduced. External methods have read and write access to AssEmbly memory and registers.
- Memory allocation: A build-in, optional memory allocator has been added. You do not need to use it to read/write to memory.
- It supports the allocation, re-allocation, and freeing of memory regions with a given size.
- Regions are guaranteed to never overlap, can persist for the entire lifetime of the program, and can be used to ensure that there is enough free memory for an operation.
- Stack collision detection has been added in combination with memory allocation to detect situations where the stack has grown too large and collided with allocated heap memory. It can be disabled with the
--unmapped-stack
command line parameter.
- Executable compression: Assembled executables can now be compressed with gzip by using the
--compress
command line parameter. - The debugger now has a new
heap
command, which displays current memory statistics as well as a diagram of allocated memory. - Numerous improvements to the debugger
map
command:- The colour key is now shown at both at the beginning and the end of the table.
- There is now support for multi-coloured cells if multiple of the three registers point to the same address.
- Unmapped memory is now highlighted in grey.
- A label reference can now be used as the operand to the
NUM
assembler directive in order to insert the literal resolved address of a label into memory. - A new code suggestion has been added that discourages the use of
AND
when a move instruction can be used instead. - Additional cases have been added for the "Operation has no effect" suggestion.
- The next instruction to execute is now printed after extra debug information in the debugger.
- The default memory size has been increased to 8KB.
Fixes:
- ADI files now correctly show the pre- and post-resolution paths for imported files.
Example program changes:
- New example programs that demonstrate C# interoperation have been included.
- The QOI example program has been modified to utilise the new memory allocation extension set.
- Included solutions for some days of 2023's Advent of Code.
- The solution to Day 1 of 2022's Advent of Code has been slightly simplified.
- Comments that are no longer necessary due to the increased default memory size have been removed.
Internal changes:
- The published executable is no longer built as self-contained.
- The project has been upgraded to .NET 8.
- Warnings are now treated as errors when publishing the application.
- Most struct definitions have been moved to a separate file, along with a new Range struct designed for use with memory region tracking.
- The
Processor
class now contains methods for memory region management (allocation, re-allocation, and freeing). - The test folder has been renamed from
AssEmbly.Test
to justTest
. - The reference manual is now also compiled into a PDF.
- The strict grammar definitions have been removed.
Documentation Errors
- The first code example in the "Address" subsection of the "Operand Types" section should use
MVB
, notMVQ
.
Release 2.1.0
.NET 6, Self-contained (.NET install not required)
Additions:
- Character literals: The language now has support for character literals surrounded by single quotes. These contain a single character only and are assembled into numeric literals representing the UTF-8 encoding of the contained character. Some examples include:
MVQ rg0, 'a'
, which will assemble toMVQ rg0, 97
CMP rg1, '\n'
, which will assemble toCMP rg1, 10
WCN '\u30C8'
, which will assemble toWCN 8946659
Fixes:
- The REPL environment will no longer convert some special characters to question marks.
- The
stack
debugger command will no longer cause a crash when used in a subroutine with no parent stack. - Invalid syntax where a label definition would contain a space followed by additional characters will no longer be ignored silently.
- Numerous additional syntax errors now have checks that provide descriptive error messages and VSCode linting, replacing previous generic errors such as "IndexOutOfRangeException".
Example program changes:
- Example programs that used numeric values to represent characters now use character literals instead.
- The
read_file.asm
example program has been updated with a slight code size optimisation and an error message for non-existent files.
Internal changes:
- All applicable strings in the code have been moved to an external resource file to aid any potential future localisation.
- The BNF graphs have been removed.
FLPT_WFN
now explicitly uses the Invariant culture when converting to a string and writing.- General code refactoring has been carried out to remove or shorten redundant code and to make the code style more consistent.
Documentation Errors
- The first code example in the "Address" subsection of the "Operand Types" section should use
MVB
, notMVQ
.
Release 2.0.0
.NET 6, Self-contained (.NET install not required)
Additions:
- Floating point support: There is now full support for performing operations on floating point numbers. This includes, but is not limited to:
- Support for floating point literals (e.g.
2.0
,-5.12
, and.63
) in source code. - Floating point math: standard addition, subtraction, multiplication and division - plus trigonometry, exponentiation and logarithms.
- Instructions for converting between integers and floats with different forms of rounding: truncation, ceiling, floor, and nearest even.
- Instructions for writing floating point values to the console and files.
- Support for converting between floating point formats:
float16
(half precision),float32
(single precision), andfloat64
(double precision). Keep in mind that onlyfloat64
(double precision) is supported for all other floating point operations in the language.
- Support for floating point literals (e.g.
- Signed support: There is now full support for performing operations on two's complement signed numbers. This includes, but is not limited to:
- New sign and overflow status flags.
- Support for signed literals (e.g.
-5
) in source code. - Signed math: addition, subtraction, and multiplication can be performed with the existing instructions. Signed division can be performed with the newly added instructions, along with negation.
- Signed jump instructions: these use the values of the newly added status flags to jump based on signed comparison logic.
- Sign extension: this allows conversion from smaller signed values (byte/word/dword) to full, 64-bit signed values.
- Instructions for writing signed values to the console and files.
- REPL environment: There is now a built-in REPL environment that allows you to enter instructions and have them execute and display their result in real-time. It can be accessed by using the
repl
operation in the command line. - AAP file format: The AAP file format has been updated to include a file header, providing information such as the version the file is compiled for, and features that the program in the file uses. Backwards compatibility with the old format is achieved with the
--v1-format
command line parameter. - Entry points: You can now specify the starting location for a program using the
:ENTRY
label. Programs will still start executing from the top if this label isn't specified. - There is now a new "byte swap" (
EXTD_BSW
) instruction to reverse byte order in a register, thereby converting between little and big endian. - Macro definitions now ignore most standard syntax rules, allowing them to be much more diverse in content.
- The
stack
command in the debugger now takes an optional parameter to limit the number of values printed. - Programs will now have the version they were compiled for checked before they are executed, issuing a warning if they were built for a newer version.
- The debugger now shows the signed and floating point value of registers where applicable.
- The debugger now displays which status flags are set along with the full register printout.
- Some errors related to file handling now output more easily understandable error messages.
- The disassembler will now specify the address of invalid labels with a comment.
Fixes:
- Writing base 10 numbers to files no longer causes raw bytes to be inserted first.
- Using relative paths containing subdirectories as command line parameters now works as expected.
MUL
will no longer set the carry flag when the multiplier is 0.TST
andCMP
will no longer throw an error when used with therpo
register.- Strings with leading/trailing double quotes as a part of the string body no longer cause issues resulting from leftover code from the old parser.
RFC
now checks that a file is open and has remaining characters before attempting to read.- A warning suggesting the use of
HLT
will no longer be issued if a file contains only data insertion directives. - Directives will no longer attempt to parse label literals as numeric values.
Example program changes:
- Some examples have been altered to use the new features provided in this release.
Internal changes:
- To facilitate the large number of new opcodes now required for floating point and signed support, the concept of extension sets has been implemented. Opcodes can now be either 1 or 3 bytes long, with 3 byte opcodes following this format:
0xFF, ExtensionSet, InstructionCode
. Single byte opcodes will behave as they always did, corresponding to instruction codes in the base instruction set (0x00
). - The call stack is now more efficient: only
rpo
andrsb
are pushed when calling a function now, whereasrso
would have also been unnecessarily pushed before. Backwards compatibility with the old calling convention is achieved with the--v1-call-stack
command line parameter. - The header is now printed to stderr instead of stdout, preventing it from being included when piping the process output to another process or a file.
- Unit tests have been included for every single opcode in the processor.
- Enums are no longer contained within the
Data
class, now they are a direct part of the rootAssEmbly
namespace. - The
parsedNumber
out parameter forAssembler.ParseLiteral
is now used in additional places. - A PowerShell script for building the reference manual documentation has been added.
- BNF grammar definitions, along with representing graphs, have been added.
Program.cs
has been completely refactored, deduplicating large sections of code.- The number of local variables in the
Processor.Execute
method has been reduced. - The implementation of the
RNG
instruction has been simplified.
Documentation Errors
- The first code example in the "Address" subsection of the "Operand Types" section should use
MVB
, notMVQ
.
Release 1.1.1
.NET 6, Self-contained (.NET install not required)
Patch changes (1.1.0 -> 1.1.1):
- Fixed an issue where errors raised by references to non-existent labels wouldn't be communicated correctly to the VSCode extension
Release changes (1.0.0 -> 1.1.0):
Additions:
- Assembler warnings: The assembler will now alert you when common mistakes and possible improvements are detected in your source code. This is accompanied with a new assembler directive and command line parameters to control whether or not individual warnings are raised.
- Escape sequences: You can now use escape sequences like \n and \0 in strings.
- Performance: AssEmbly 1.1.0 is on average 8.7x faster than 1.0.0. [1] This now makes it comparatively faster than Python. [2]
- Breakpoints: The debugger now has support for breaking when a register becomes equal to a specified value.
- Assembler error messages now show the particular line and file the error occurred on, and are no longer incorrect when following an
IMP
directive. - Assembler errors given when a non-existent label is referenced now tell you what line the reference was made on.
- Circular imports are now detected and prevent assembly, where before they would cause an infinite loop.
- Support for JSON communication with the VSCode extension to provide diagnostics in the editor has been added.
Fixes:
- File/console input/output now work correctly with UTF-8 characters that require multiple bytes. Instructions will now read and write these characters one byte at a time without modifying them, and will display correctly when they're output together.
- The processor will now correctly crash if
rpo
is given as the second operand toDVR
.
Example program changes:
- The calculator example no longer returns incorrect results if the second value is shorter in decimal representation than the first.
- All examples have been altered to use the new features provided in this release, as well as to ensure they follow all the suggestions given by the assembler.
Internal changes:
Program.cs
has been refactored into separate methods with the Debugger being moved into its own file. All#region
directives have been removed.- The majority of exceptions now use classes defined specifically for use in AssEmbly, with some new properties such as a
ConsoleMessage
. - The value of the status flag register is now mapped to a Flag enum. The un-setting of bits in the register has also been simplified.
- Regular expressions are no longer used as a fundamental part of parsing source code lines.
- The
mem-size
parameter now has it's value validated, with the application quitting gracefully instead of crashing if it is not valid. - The
Step
andExecute
methods in the processor have been merged, contributing to most of the performance gains in this release. - The methods the processor uses to read and write values in memory have all been renamed with more descriptive names.
Footnotes:
[1]: Tested with the QOI example program (Example Programs/qoi.ext.asm
) on an image 616 x 995 pixels in size. Averaged over 100 trials for each test, all executed synchronously. Exact values were 367.107ms
for 1.1.0, 3,178.963ms
for 1.0.0. The same image and assembled program binary were used for both tests. CPU was an Intel i9-12900K running Windows 11 Pro 22621.2134 and .NET CLR 6.0.21. Both versions were compiled for release (optimisations enabled) by the same compiler (Roslyn 4.7.0-3.23403.2).
[2]: Tested with a simple loop program that increments a single variable 100,000,000 times, then prints it to the console. Python 3.11.4 x64 (CPython) was utilised. CPU/Windows version the same as above. Your mileage may vary depending on use case.
Documentation Errors
The following errors have been found in the documentation since this release:
- The "Instruction Count" field in the "Technical Information" table is incorrect. It should read "167 opcodes (49 unique operations)", not "165 opcodes (48 unique operations)".
- The "Labels" section claims that, in the third example,
:END
will have a value of34
when referenced as each instruction will take up17
bytes. These numbers should actually be20
and10
respectively. - The start of the "Maths and Bitwise Operations" section says that 4 bytes will be read from memory for these operations, when in fact 8 bytes will be read.
- The "Reading and Writing" subsection of the "File Handling" section contains an error. It says that new data written to an existing file "will be appended to the end". This is not correct. New data "will start overwriting from the first byte in the file. Any remaining data that does not get overwritten will remain unchanged, and the size of the file will not change unless more bytes are written than were originally in the file. To clear a file before writing it, use the
DFL
instruction to delete the file beforehand." - The first code example in the "Address" subsection of the "Operand Types" section should use
MVB
, notMVQ
.
Release 1.1.0
.NET 6, Self-contained (.NET install not required)
Additions:
- Assembler warnings: The assembler will now alert you when common mistakes and possible improvements are detected in your source code. This is accompanied with a new assembler directive and command line parameters to control whether or not individual warnings are raised.
- Escape sequences: You can now use escape sequences like \n and \0 in strings.
- Performance: AssEmbly 1.1.0 is on average 8.7x faster than 1.0.0. [1] This now makes it comparatively faster than Python. [2]
- Breakpoints: The debugger now has support for breaking when a register becomes equal to a specified value.
- Assembler error messages now show the particular line and file the error occurred on, and are no longer incorrect when following an
IMP
directive. - Assembler errors given when a non-existent label is referenced now tell you what line the reference was made on.
- Circular imports are now detected and prevent assembly, where before they would cause an infinite loop.
- Support for JSON communication with the VSCode extension to provide diagnostics in the editor has been added.
Fixes:
- File/console input/output now work correctly with UTF-8 characters that require multiple bytes. Instructions will now read and write these characters one byte at a time without modifying them, and will display correctly when they're output together.
- The processor will now correctly crash if
rpo
is given as the second operand toDVR
.
Example program changes:
- The calculator example no longer returns incorrect results if the second value is shorter in decimal representation than the first.
- All examples have been altered to use the new features provided in this release, as well as to ensure they follow all the suggestions given by the assembler.
Internal changes:
Program.cs
has been refactored into separate methods with the Debugger being moved into its own file. All#region
directives have been removed.- The majority of exceptions now use classes defined specifically for use in AssEmbly, with some new properties such as a
ConsoleMessage
. - The value of the status flag register is now mapped to a Flag enum. The un-setting of bits in the register has also been simplified.
- Regular expressions are no longer used as a fundamental part of parsing source code lines.
- The
mem-size
parameter now has it's value validated, with the application quitting gracefully instead of crashing if it is not valid. - The
Step
andExecute
methods in the processor have been merged, contributing to most of the performance gains in this release. - The methods the processor uses to read and write values in memory have all been renamed with more descriptive names.
Footnotes:
[1]: Tested with the QOI example program (Example Programs/qoi.ext.asm
) on an image 616 x 995 pixels in size. Averaged over 100 trials for each test, all executed synchronously. Exact values were 367.107ms
for 1.1.0, 3,178.963ms
for 1.0.0. The same image and assembled program binary were used for both tests. CPU was an Intel i9-12900K running Windows 11 Pro 22621.2134 and .NET CLR 6.0.21. Both versions were compiled for release (optimisations enabled) by the same compiler (Roslyn 4.7.0-3.23403.2).
[2]: Tested with a simple loop program that increments a single variable 100,000,000 times, then prints it to the console. Python 3.11.4 x64 (CPython) was utilised. CPU/Windows version the same as above. Your mileage may vary depending on use case.
Documentation Errors
The following errors have been found in the documentation since this release:
- The "Instruction Count" field in the "Technical Information" table is incorrect. It should read "167 opcodes (49 unique operations)", not "165 opcodes (48 unique operations)".
- The "Labels" section claims that, in the third example,
:END
will have a value of34
when referenced as each instruction will take up17
bytes. These numbers should actually be20
and10
respectively. - The start of the "Maths and Bitwise Operations" section says that 4 bytes will be read from memory for these operations, when in fact 8 bytes will be read.
- The "Reading and Writing" subsection of the "File Handling" section contains an error. It says that new data written to an existing file "will be appended to the end". This is not correct. New data "will start overwriting from the first byte in the file. Any remaining data that does not get overwritten will remain unchanged, and the size of the file will not change unless more bytes are written than were originally in the file. To clear a file before writing it, use the
DFL
instruction to delete the file beforehand." - The first code example in the "Address" subsection of the "Operand Types" section should use
MVB
, notMVQ
.
Release 1.0.0
First official release
.NET 6, Self-contained (.NET install not required)
Changes from last pre-release (1.0.0-pre14):
- Reading from/writing to binary files now works as expected
- Fixed an issue where using
OFL
orDFL
on a pointer would causerpo
to point to the incorrect next instruction - Fixed an issue where pushing the value of
rso
to the stack would cause it's new value, not it's old one to be pushed - Added a new starting offset parameter to the "map" command in the debugger
- Added a version number to the header printout, plus a new "--version" parameter
Documentation Errors
The following errors have been found in the documentation since this release:
- The "Instruction Count" field in the "Technical Information" table is incorrect. It should read "167 opcodes (49 unique operations)", not "165 opcodes (48 unique operations)".
- The "Labels" section claims that, in the third example,
:END
will have a value of34
when referenced as each instruction will take up17
bytes. These numbers should actually be20
and10
respectively. - The start of the "Maths and Bitwise Operations" section says that 4 bytes will be read from memory for these operations, when in fact 8 bytes will be read.
- The "Reading and Writing" subsection of the "File Handling" section contains an error. It says that new data written to an existing file "will be appended to the end". This is not correct. New data "will start overwriting from the first byte in the file. Any remaining data that does not get overwritten will remain unchanged, and the size of the file will not change unless more bytes are written than were originally in the file. To clear a file before writing it, use the
DFL
instruction to delete the file beforehand." - The first code example in the "Address" subsection of the "Operand Types" section should use
MVB
, notMVQ
.
Pre-release 1.0.0-pre14
Self-contained, ready-to-run, .NET 6, Win x64
- New instruction!
FSZ
- Get size of a file in bytes - Fixed issue where reading a debug file with empty sections would cause it to fail to load