The NewASM compiler does several different optimizations by default before packing your app into a binary file. Below is a list of optimizations compiler will do.
The compiler will of course perform minor peephole optimizations such as:
peephole optimization, removed redundant double code
Code such as double jumps, double returns, or double reassignments, for example:
mov tlr, 3
mov tlr, 3 ; removed, it is already 3jmp lmao
jmp smth ; removed, this line will never be reachedremoved redundant try-catch block
Empty try-catch blocks will be ultimatively removed from the binary as they're relatively expensive.
try
; no code
catch xdpeephole optimization, removed redundant refetch
Double fetch instructions are removed.
peephole optimization, removed redundant stack memory dedication
Double resb instructions are removed.
peephole optimization, removed redundant kernel module entrance
Double sysenter instructions are removed.
peephole optimization, removed redundant memory alignment
Double align instructions are removed.
peephole optimization, value of a register changed to itself
Code such as:
mov tlr, *tlrwill also get removed by the compiler.
peephole optimization, removed dead code
Dead instructions like rem will get removed.
peephole optimization, removed redundant assignment before reassignment
Code like this will also be modified:
mov tlr, 6 ; removed cuz the next instruction's modifying tlr again
mov tlr, *tlr removed redundant code section reset
Redundant code section modifiers are also removed.
.start
; code
.start ; removed
; more codeAlthough this looks like a very simple optimization, it requires some deeper code analysis by the compiler in order to determine if the removal is 100% safe.
removed unreachable code block
The compiler also does deeper code analysis in order to remove unreachable code blocks such as:
jmp lmao
; all of this code between there 2 lines will get removed, including the jmp ins above
; :lmao remains because the rest of the code may use it
:lmao
removed useless namespace labels
The compiler also removes empty namespaces. By empty, it means no procedure, thread, data container or a variable is declared within it.
.start
; empty namespace
./lmao
nop
mov rax, 0
lea tuple, 3
; ... etc
./!lmao
; namespace with elements
./lmao
proc func
halt 0
end
; it is gonna detect empty nested namespaces
; the compiler creates a complex tree of namespaces
; analyses it from top to bottom
./lmao2
./!lmao3
./!lmao