Skip to main content

Low-Level

This page is still under construction!

Abstractions are made to make the programmer's life easier, symplifying repedititve or system-dependent tasks.

Sometimes however, it is mandatory to communicate directly with the system. Embedded and bare-metal development, system programming and better memory managing are just some examples of why this access is needed.


Acessing CPU Registers

This feature is still not implemented!

When compiled to some CPUs, the program binary has access to a set of CPU Registers that are used to do operations or controll the CPU behavior.

// TODO


Inline Assembly

This feature is still not implemented!

When read and write to the registers themselves are not enough, Abstract has a rich system that allow the user to write an entire assembly subroutine.

As a example of use, being targeted to x86_64 assemby:

from Std.Console import
from Std.System.Assembly.x86_64Assembly import { assemblyContext }

func foo() {

let string message = "Hello, World!"

# Calling writeln(message) though assembly

# This will create the context object.
# The context object is used to store the
# entire assembly code in a tiny scope,
# allowing that the code will be emited as
# is and do not receive any optimizations.
assemblyContext()

# The context return an instance that contains
# diverse methods to write the assembly code.
# See the example:

# The first argument must go in the RAX register
# the mov instruction follows the order 'to <- from'
.MOV(.rax, message)
# Then we can make a call to the function pointer
.CALL(&writeln)

#This is equivalent to
###
MOV $rax, message
CALL Std.Console.writeln
###

}
from Std.Console import
from Std.System.Assembly.x86_64Assembly import { assemblyContext }

func say_message(string message) {

assemblyContext()

# This code makes a system call in a linux environment.
# This code is also targeted to x86 machines.

.MOV(.eax, 4) # sys_write
.MOV(.ebx, 1) # stdout
.MOV(.ecx, message.buffer)
.MOV(.edx, message.length)
.INT(0x80)

}