Skip to content

Structure of a Jasmin program

MrDaiki edited this page Oct 23, 2024 · 4 revisions

A Jasmin program is a collection of:

  • parameters;
  • global variables;
  • functions.

Require

Since version 2022.04.0, a program may be split into several files using a require clause. Its simplest form is as follows

require "path/file.jinc"

Relative paths are resolved relative to the current file.

The required file is treated (mostly) as if its contents were put in place of the require clause.

Files can also be searched in named locations, for instance:

from AES require "aes.jinc"

This clause requires the file aes.jinc that is located in a path named AES. There are two ways to give names to paths in the file-system:

  • either on the command-line using the argument -I AES:actual/path/;
  • or using the JASMINPATH environment variable, as in export JASMINPATH=AES=actual/path/.

If several paths must be named, the -I argument can be used multiple times, and in the environment variable value, several ID=path pairs can be separated by a colon (:).

Parameters

A parameter is a named value. The name can be used within types (e.g., as the size of an array): as such, they can be used to provide a limited form of genericity.

Parameters are removed by the compiler right after parsing; in particular, they do not appear in the Coq abstract syntax. Therefore, they have no formal semantics.

A parameter is introduced by the param keyword, followed by a type, a name, and the value. For instance:

param int cROUNDS = 2;

Types Aliases

Jasmin compiler latest development version (still unreleased) introduced a new syntax feature for type definition. A type alias can be defined at top level of a program or a namespace. The aim of this feature is to improve genericity of Jasmin code. The types aliases are resolved like params, during parsing.

To define a type alias, we introduced the type keyword, which is followed by a name, and the a type. For example :

type reg_size = u64;

Defined types can then be used in programs in place of the compiler types.

reg reg_size a; //declaring variable a with type reg_size
reg reg_size[10] b; //declaring an array with elements of type reg_size

We can note that the feature doesn't allow definitions like :

type x = reg u64;

We can consider that the storage type (reg, stack, inline ...) is similar to the declaration keyword let in other languages (for instance Rust). Storage type is thus not a type, and should not be aliased.

Global variables

A global variable is a named valued. Unlike parameters, said value is not available at compile-time (i.e., it cannot be used as part of a type), but it is available at run-time.

Technically, global variables are stored in the code segment and are accessed to using PC-relative addressing mode.

There is no keyword to introduce a global variable declaration at the top-level, only its type, name, and value. For instance:

u128 rotate24pattern = (16u8)[ 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 ];

In this example, the value is a 128-bit machine-word, described as a vector of 16 8-bit machine-words.

Functions

A function is introduced using the fn keyword, followed by the function name, the list of its parameters, its return type (if any), and its body. The body begins with the declaration of local variables and ends with a return statement.

Here is an example function:

inline
fn shift(reg u128 x, inline int count) -> reg u128 {
  reg u128 r;
  r = #VPSLL_4u32(x, count);
  return r;
}

A function definition may be prefixed with either the inline keyword or the export keyword to denote, respectively, that the function will be removed by the compiler or that it will be present in the final assembly code and respect the target calling conventions.

Functions that are not marked with inline or export are local functions: they will be preserved by the compiler but are not visible from the outside (i.e, they cannot be called from non-Jasmin code). This feature has been introduced in version 2022.04.0.

Clone this wiki locally