Looking for help!
Name
Nasm::X86 - Generate X86 assembler code using Perl as a macro pre-processor.
Synopsis
Write and execute x64 instructions using Perl as a macro assembler as shown in the following examples.
Examples
Avx512 instructions
Use avx512 instructions to do 64 comparisons in parallel:
my $P = "2F"; # Value to test for
my $l = Rb 0; Rb $_ for 1..RegisterSize zmm0; # 0..63
Vmovdqu8 zmm0, "[$l]"; # Load data to test
PrintOutRegisterInHex zmm0;
Mov rax, "0x$P"; # Broadcast the value to be tested
Vpbroadcastb zmm1, rax;
PrintOutRegisterInHex zmm1;
for my $c(0..7) # Each possible test
{my $m = "k$c";
Vpcmpub $m, zmm1, zmm0, $c;
PrintOutRegisterInHex $m;
}
Kmovq rax, k0; # Count the number of trailing zeros in k0
Tzcnt rax, rax;
PrintOutRegisterInHex rax;
is_deeply Assemble, <<END; # Assemble and test
zmm0: 3F3E 3D3C 3B3A 3938 3736 3534 3332 3130 2F2E 2D2C 2B2A 2928 2726 2524 2322 2120 1F1E 1D1C 1B1A 1918 1716 1514 1312 1110 0F0E 0D0C 0B0A 0908 0706 0504 0302 0100
zmm1: 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F 2F2F
k0: 0000 8000 0000 0000
k1: FFFF 0000 0000 0000
k2: FFFF 8000 0000 0000
k3: 0000 0000 0000 0000
k4: FFFF 7FFF FFFF FFFF
k5: 0000 FFFF FFFF FFFF
k6: 0000 7FFF FFFF FFFF
k7: FFFF FFFF FFFF FFFF
rax: 0000 0000 0000 002F
END
Dynamic string held in an arena
Create a dynamic byte string, add some content to it, write the byte string to stdout:
my $a = CreateByteString; # Create a string
my $b = CreateByteString; # Create a string
$a->q('aa');
$b->q('bb');
$a->q('AA');
$b->q('BB');
$a->q('aa');
$b->q('bb');
$a->out;
$b->out;
PrintOutNL;
is_deeply Assemble, <<END; # Assemble and execute
aaAAaabbBBbb
END
Process management
Start a child process and wait for it, printing out the process identifiers of each process involved:
Fork; # Fork
Test rax,rax;
If # Parent
{Mov rbx, rax;
WaitPid;
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
GetPid; # Pid of parent as seen in parent
Mov rcx,rax;
PrintOutRegisterInHex rcx;
}
sub # Child
{Mov r8,rax;
PrintOutRegisterInHex r8;
GetPid; # Child pid as seen in child
Mov r9,rax;
PrintOutRegisterInHex r9;
GetPPid; # Parent pid as seen in child
Mov r10,rax;
PrintOutRegisterInHex r10;
};
my $r = Assemble;
# r8: 0000 0000 0000 0000 #1 Return from fork as seen by child
# r9: 0000 0000 0003 0C63 #2 Pid of child
# r10: 0000 0000 0003 0C60 #3 Pid of parent from child
# rax: 0000 0000 0003 0C63 #4 Return from fork as seen by parent
# rbx: 0000 0000 0003 0C63 #5 Wait for child pid result
# rcx: 0000 0000 0003 0C60 #6 Pid of parent
Read a file
Read this file:
ReadFile(Vq(file, Rs($0)), (my $s = Vq(size)), my $a = Vq(address)); # Read file
$a->setReg(rax); # Address of file in memory
$s->setReg(rdi); # Length of file in memory
PrintOutMemory; # Print contents of memory to stdout
my $r = Assemble(1 => (my $f = temporaryFile)); # Assemble and execute
ok fileMd5Sum($f) eq fileMd5Sum($0); # Output contains this file
Call functions in Libc
Call C functions by naming them as external and including their library:
my $format = Rs "Hello %s\n";
my $data = Rs "World";
Extern qw(printf exit malloc strcpy); Link 'c';
CallC 'malloc', length($format)+1;
Mov r15, rax;
CallC 'strcpy', r15, $format;
CallC 'printf', r15, $data;
CallC 'exit', 0;
ok Assemble(eq => <<END);
Hello World
END
Installation
The Intel Software Development Emulator will be required if you do not have a computer with the avx512 instruction set and wish to execute code containing these instructions. For details see:
The Networkwide Assembler is required to assemble the code produced For full details see:
https://github.com/philiprbrenan/NasmX86/blob/main/.github/workflows/main.yml
Execution Options
The "Assemble(%)" function takes the keywords described below to control assembly and execution of the assembled code:
"Assemble(%)" runs the generated program after a successful assembly unless the keep option is specified. The output on stdout is captured in file zzzOut.txt and that on stderr is captured in file zzzErr.txt.
The amount of output displayed is controlled by the debug keyword.
The eq keyword can be used to test that the output by the run.
The output produced by the program execution is returned as the result of the "Assemble(%)" function.
Keep
To produce a named executable without running it, specify:
keep=>"executable file name"
Emulator
To run the executable produced by "Assemble(%)" without the Intel emulator, which is used by default if it is present, specify:
emulator=>0
eq
The eq keyword supplies the expected output from the execution of the assembled program. If the expected output is not obtained on stdout then we confess and stop further testing. Output on stderr is ignored for test purposes.
The point at which the wanted output diverges from the output actually got is displayed to assist debugging as in:
Comparing wanted with got failed at line: 4, character: 22
Start:
k7: 0000 0000 0000 0001
k6: 0000 0000 0000 0003
k5: 0000 0000 0000 0007
k4: 0000 0000 000
Want ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 0002
k3: 0000 0000 0000 0006
k2: 0000 0000 0000 000E
k1: 0000 0000
Got ________________________________________________________________________________
0 0002
k3: 0000 0000 0000 0006
k2: 0000 0000 0000 000E
k1: 0000 0000
Debug
The debug keyword controls how much output is printed after each assemble and run.
debug => 0
produces no output unless the eq keyword was specified and the actual output fails to match the expected output. If such a test fails we Carp::confess.
debug => 1
shows all the output produces and conducts the test specified by the eq is present. If the test fails we Carp::confess.
debug => 2
shows all the output produces and conducts the test specified by the eq is present. If the test fails we continue rather than calling Carp::confess.
Description
Generate X86 assembler code using Perl as a macro pre-processor.
Version "20210629".
The following sections describe the methods in each functional area of this module. For an alphabetic listing of all methods by name see Index.
Data
Layout data
SetLabel($l)
Set a label in the code section
Parameter Description
1 $l Label
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax;
Ds(@d)
Layout bytes in memory and return their label
Parameter Description
1 @d Data to be laid out
Example:
my $q = Rs('a'..'z');
Mov rax, Ds('0'x64); # Output area # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Vmovdqu32(xmm0, "[$q]"); # Load
Vprolq (xmm0, xmm0, 32); # Rotate double words in quad words
Vmovdqu32("[rax]", xmm0); # Save
Mov rdi, 16;
PrintOutMemory;
ok Assemble =~ m(efghabcdmnopijkl)s;
Rs(@d)
Layout bytes in read only memory and return their label
Parameter Description
1 @d Data to be laid out
Example:
Comment "Print a string from memory";
my $s = "Hello World";
Mov rax, Rs($s); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rdi, length $s;
PrintOutMemory;
ok Assemble =~ m(Hello World);
my $q = Rs('abababab'); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov(rax, 1);
Mov(rbx, 2);
Mov(rcx, 3);
Mov(rdx, 4);
Mov(r8, 5);
Lea r9, "[rax+rbx]";
PrintOutRegistersInHex;
my $r = Assemble;
ok $r =~ m( r8: 0000 0000 0000 0005.* r9: 0000 0000 0000 0003.*rax: 0000 0000 0000 0001)s;
ok $r =~ m(rbx: 0000 0000 0000 0002.*rcx: 0000 0000 0000 0003.*rdx: 0000 0000 0000 0004)s;
Db(@bytes)
Layout bytes in the data segment and return their label
Parameter Description
1 @bytes Bytes to layout
Example:
my $s = Rb 0; Rb 1; Rw 2; Rd 3; Rq 4;
my $t = Db 0; Db 1; Dw 2; Dd 3; Dq 4; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Vmovdqu8 xmm0, "[$s]";
Vmovdqu8 xmm1, "[$t]";
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
Sub rsp, 16;
Mov rax, rsp; # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Mov rdi, 16;
Mov rsi, $s;
CopyMemory(Vq(source, rsi), Vq(target, rax), Vq(size, rdi));
PrintOutMemoryInHex;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(xmm1: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(0001 0200 0300 00000400 0000 0000 0000);
Dw(@words)
Layout words in the data segment and return their label
Parameter Description
1 @words Words to layout
Example:
my $s = Rb 0; Rb 1; Rw 2; Rd 3; Rq 4;
my $t = Db 0; Db 1; Dw 2; Dd 3; Dq 4; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Vmovdqu8 xmm0, "[$s]";
Vmovdqu8 xmm1, "[$t]";
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
Sub rsp, 16;
Mov rax, rsp; # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Mov rdi, 16;
Mov rsi, $s;
CopyMemory(Vq(source, rsi), Vq(target, rax), Vq(size, rdi));
PrintOutMemoryInHex;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(xmm1: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(0001 0200 0300 00000400 0000 0000 0000);
Dd(@dwords)
Layout double words in the data segment and return their label
Parameter Description
1 @dwords Double words to layout
Example:
my $s = Rb 0; Rb 1; Rw 2; Rd 3; Rq 4;
my $t = Db 0; Db 1; Dw 2; Dd 3; Dq 4; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Vmovdqu8 xmm0, "[$s]";
Vmovdqu8 xmm1, "[$t]";
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
Sub rsp, 16;
Mov rax, rsp; # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Mov rdi, 16;
Mov rsi, $s;
CopyMemory(Vq(source, rsi), Vq(target, rax), Vq(size, rdi));
PrintOutMemoryInHex;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(xmm1: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(0001 0200 0300 00000400 0000 0000 0000);
Dq(@qwords)
Layout quad words in the data segment and return their label
Parameter Description
1 @qwords Quad words to layout
Example:
my $s = Rb 0; Rb 1; Rw 2; Rd 3; Rq 4;
my $t = Db 0; Db 1; Dw 2; Dd 3; Dq 4; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Vmovdqu8 xmm0, "[$s]";
Vmovdqu8 xmm1, "[$t]";
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
Sub rsp, 16;
Mov rax, rsp; # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Mov rdi, 16;
Mov rsi, $s;
CopyMemory(Vq(source, rsi), Vq(target, rax), Vq(size, rdi));
PrintOutMemoryInHex;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(xmm1: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(0001 0200 0300 00000400 0000 0000 0000);
Rb(@bytes)
Layout bytes in the data segment and return their label
Parameter Description
1 @bytes Bytes to layout
Example:
my $s = Rb 0; Rb 1; Rw 2; Rd 3; Rq 4; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $t = Db 0; Db 1; Dw 2; Dd 3; Dq 4;
Vmovdqu8 xmm0, "[$s]";
Vmovdqu8 xmm1, "[$t]";
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
Sub rsp, 16;
Mov rax, rsp; # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Mov rdi, 16;
Mov rsi, $s;
CopyMemory(Vq(source, rsi), Vq(target, rax), Vq(size, rdi));
PrintOutMemoryInHex;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(xmm1: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(0001 0200 0300 00000400 0000 0000 0000);
Rw(@words)
Layout words in the data segment and return their label
Parameter Description
1 @words Words to layout
Example:
my $s = Rb 0; Rb 1; Rw 2; Rd 3; Rq 4; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $t = Db 0; Db 1; Dw 2; Dd 3; Dq 4;
Vmovdqu8 xmm0, "[$s]";
Vmovdqu8 xmm1, "[$t]";
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
Sub rsp, 16;
Mov rax, rsp; # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Mov rdi, 16;
Mov rsi, $s;
CopyMemory(Vq(source, rsi), Vq(target, rax), Vq(size, rdi));
PrintOutMemoryInHex;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(xmm1: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(0001 0200 0300 00000400 0000 0000 0000);
Rd(@dwords)
Layout double words in the data segment and return their label
Parameter Description
1 @dwords Double words to layout
Example:
my $s = Rb 0; Rb 1; Rw 2; Rd 3; Rq 4; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $t = Db 0; Db 1; Dw 2; Dd 3; Dq 4;
Vmovdqu8 xmm0, "[$s]";
Vmovdqu8 xmm1, "[$t]";
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
Sub rsp, 16;
Mov rax, rsp; # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Mov rdi, 16;
Mov rsi, $s;
CopyMemory(Vq(source, rsi), Vq(target, rax), Vq(size, rdi));
PrintOutMemoryInHex;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(xmm1: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(0001 0200 0300 00000400 0000 0000 0000);
Rq(@qwords)
Layout quad words in the data segment and return their label
Parameter Description
1 @qwords Quad words to layout
Example:
my $s = Rb 0; Rb 1; Rw 2; Rd 3; Rq 4; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $t = Db 0; Db 1; Dw 2; Dd 3; Dq 4;
Vmovdqu8 xmm0, "[$s]";
Vmovdqu8 xmm1, "[$t]";
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
Sub rsp, 16;
Mov rax, rsp; # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Mov rdi, 16;
Mov rsi, $s;
CopyMemory(Vq(source, rsi), Vq(target, rax), Vq(size, rdi));
PrintOutMemoryInHex;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(xmm1: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(0001 0200 0300 00000400 0000 0000 0000);
Float32($float)
32 bit float
Parameter Description
1 $float Float
Float64($float)
64 bit float
Parameter Description
1 $float Float
Registers
Operations on registers
xmm(@r)
Add xmm to the front of a list of register expressions
Parameter Description
1 @r Register numbers
ymm(@r)
Add ymm to the front of a list of register expressions
Parameter Description
1 @r Register numbers
zmm(@r)
Add zmm to the front of a list of register expressions
Parameter Description
1 @r Register numbers
Save and Restore
Saving and restoring registers via the stack
SaveFirstFour(@keep)
Save the first 4 parameter registers making any parameter registers read only
Parameter Description
1 @keep Registers to mark as read only
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax;
RestoreFirstFour()
Restore the first 4 parameter registers
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax;
RestoreFirstFourExceptRax()
Restore the first 4 parameter registers except rax so it can return its value
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax;
RestoreFirstFourExceptRaxAndRdi()
Restore the first 4 parameter registers except rax and rdi so we can return a pair of values
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax;
SaveFirstSeven()
Save the first 7 parameter registers
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax;
RestoreFirstSeven()
Restore the first 7 parameter registers
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax;
RestoreFirstSevenExceptRax()
Restore the first 7 parameter registers except rax which is being used to return the result
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax;
RestoreFirstSevenExceptRaxAndRdi()
Restore the first 7 parameter registers except rax and rdi which are being used to return the results
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax;
ReorderSyscallRegisters(@registers)
Map the list of registers provided to the 64 bit system call sequence
Parameter Description
1 @registers Registers
Example:
Mov rax, 1; Mov rdi, 2; Mov rsi, 3; Mov rdx, 4;
Mov r8, 8; Mov r9, 9; Mov r10, 10; Mov r11, 11;
ReorderSyscallRegisters r8,r9; # Reorder the registers for syscall # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rdi;
UnReorderSyscallRegisters r8,r9; # Unreorder the registers to recover their original values
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rdi;
ok Assemble =~ m(rax:.*08.*rdi:.*9.*rax:.*1.*rdi:.*2.*)s;
UnReorderSyscallRegisters(@registers)
Recover the initial values in registers that were reordered
Parameter Description
1 @registers Registers
Example:
Mov rax, 1; Mov rdi, 2; Mov rsi, 3; Mov rdx, 4;
Mov r8, 8; Mov r9, 9; Mov r10, 10; Mov r11, 11;
ReorderSyscallRegisters r8,r9; # Reorder the registers for syscall
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rdi;
UnReorderSyscallRegisters r8,r9; # Unreorder the registers to recover their original values # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rdi;
ok Assemble =~ m(rax:.*08.*rdi:.*9.*rax:.*1.*rdi:.*2.*)s;
RegisterSize($r)
Return the size of a register
Parameter Description
1 $r Register
Example:
Mov rax, 1;
Mov rdi, 1;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSeven;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFour;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRax;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRax;
PrintOutRegisterInHex rax, rdi;
SaveFirstFour;
Mov rax, 2;
Mov rdi, 2;
SaveFirstSeven;
Mov rax, 3;
Mov rdi, 4;
PrintOutRegisterInHex rax, rdi;
RestoreFirstSevenExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
RestoreFirstFourExceptRaxAndRdi;
PrintOutRegisterInHex rax, rdi;
Bswap rax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
is_deeply Assemble, <<END;
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0002
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0001
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0001
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0000 0000 0000 0003
rdi: 0000 0000 0000 0004
rax: 0300 0000 0000 0000
END
ok 8 == RegisterSize rax; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ClearRegisters(@registers)
Clear registers by setting them to zero
Parameter Description
1 @registers Registers
Example:
Mov rax,1;
Kmovq k0, rax;
Kaddb k0, k0, k0;
Kaddb k0, k0, k0;
Kaddb k0, k0, k0;
Kmovq rax, k0;
PushR k0;
ClearRegisters k0; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Kmovq k1, k0;
PopR k0;
PrintOutRegisterInHex k0;
PrintOutRegisterInHex k1;
ok Assemble =~ m(k0: 0000 0000 0000 0008.*k1: 0000 0000 0000 0000)s;
SetMaskRegister($mask, $start, $length)
Set the mask register to ones starting at the specified position for the specified length and zeroes elsewhere
Parameter Description
1 $mask Mask register to set
2 $start Register containing start position or 0 for position 0
3 $length Register containing end position
Example:
Mov rax, 8;
Mov rsi, -1;
Inc rsi; SetMaskRegister(k0, rax, rsi); PrintOutRegisterInHex k0; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Inc rsi; SetMaskRegister(k1, rax, rsi); PrintOutRegisterInHex k1; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Inc rsi; SetMaskRegister(k2, rax, rsi); PrintOutRegisterInHex k2; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Inc rsi; SetMaskRegister(k3, rax, rsi); PrintOutRegisterInHex k3; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Inc rsi; SetMaskRegister(k4, rax, rsi); PrintOutRegisterInHex k4; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Inc rsi; SetMaskRegister(k5, rax, rsi); PrintOutRegisterInHex k5; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Inc rsi; SetMaskRegister(k6, rax, rsi); PrintOutRegisterInHex k6; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Inc rsi; SetMaskRegister(k7, rax, rsi); PrintOutRegisterInHex k7; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply Assemble, <<END;
k0: 0000 0000 0000 0000
k1: 0000 0000 0000 0100
k2: 0000 0000 0000 0300
k3: 0000 0000 0000 0700
k4: 0000 0000 0000 0F00
k5: 0000 0000 0000 1F00
k6: 0000 0000 0000 3F00
k7: 0000 0000 0000 7F00
END
SetZF()
Set the zero flag
Example:
SetZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
ClearZF;
PrintOutZF;
SetZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
SetZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
ClearZF;
PrintOutZF;
ok Assemble =~ m(ZF=1.*ZF=0.*ZF=1.*ZF=1.*ZF=0)s;
ClearZF()
Clear the zero flag
Example:
SetZF;
PrintOutZF;
ClearZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
SetZF;
PrintOutZF;
SetZF;
PrintOutZF;
ClearZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
ok Assemble =~ m(ZF=1.*ZF=0.*ZF=1.*ZF=1.*ZF=0)s;
Tracing
Trace the execution of a program
Trace()
Add tracing code
Tracking
Track the use of registers so that we do not accidently use unset registers or write into registers that are already in use.
Keep(@target)
Mark free registers so that they are not updated until we Free them or complain if the register is already in use.
Parameter Description
1 @target Registers to keep
KeepSet($target)
Confirm that the specified registers are in use
Parameter Description
1 $target Registers to keep
KeepPush(@target)
Push the current status of the specified registers and then mark them as free
Parameter Description
1 @target Registers to keep
KeepPop(@target)
Reset the status of the specified registers to the status quo ante the last push
Parameter Description
1 @target Registers to keep
KeepReturn(@target)
Pop the specified register and mark it as in use to effect a subroutine return with this register.
Parameter Description
1 @target Registers to return
KeepFree(@target)
Free registers so that they can be reused
Parameter Description
1 @target Registers to free
Mask
Operations on mask registers
LoadConstantIntoMaskRegister($reg, $value)
Load a constant into a mask register
Parameter Description
1 $reg Mask register to load
2 $value Constant to load
Example:
Mov r14, 0;
Kmovq k0, r14;
KeepFree r14;
Ktestq k0, k0;
IfZ {PrintOutStringNL "0 & 0 == 0"};
PrintOutZF;
LoadConstantIntoMaskRegister k1, 1; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Ktestq k1, k1;
IfNz {PrintOutStringNL "1 & 1 != 0"};
PrintOutZF;
LoadConstantIntoMaskRegister k2, eval "0b".(('1'x4).('0'x4))x2; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex k0, k1, k2;
Mov r15, 0x89abcdef;
Mov r14, 0x01234567;
Shl r14, 32;
Or r15, r14;
Push r15;
Push r15;
KeepFree r15;
PopEax; PrintRaxInHex($stdout, 3); PrintOutNL; KeepFree rax;
my $a = Vq('aaaa');
$a->pop;
$a->push;
$a->outNL;
PopEax; PrintRaxInHex($stdout, 3); PrintOutNL; KeepFree rax;
ok Assemble(debug => 0, eq => <<END);
0 & 0 == 0
ZF=1
1 & 1 != 0
ZF=0
k0: 0000 0000 0000 0000
k1: 0000 0000 0000 0001
k2: 0000 0000 0000 F0F0
89AB CDEF
aaaa: 89AB CDEF 0123 4567
0123 4567
END
Structured Programming
Structured programming constructs
If($jump, $then, $else)
If
Parameter Description
1 $jump Jump op code of variable
2 $then Then - required
3 $else Else - optional
Example:
Mov rax, 0;
Test rax,rax;
IfNz
{PrintOutRegisterInHex rax;
} sub
{PrintOutRegisterInHex rbx;
};
KeepFree rax;
Mov rax, 1;
Test rax,rax;
IfNz
{PrintOutRegisterInHex rcx;
} sub
{PrintOutRegisterInHex rdx;
};
ok Assemble =~ m(rbx.*rcx)s;
Then($body)
Then body for an If statement
Parameter Description
1 $body Then body
Else($body)
Else body for an If statement
Parameter Description
1 $body Else body
IfEq($then, $else)
If equal execute the then body else the else body
Parameter Description
1 $then Then - required
2 $else Else - optional
IfNe($then, $else)
If not equal execute the then body else the else body
Parameter Description
1 $then Then - required
2 $else Else - optional
IfNz($then, $else)
If the zero is not set then execute the then body else the else body
Parameter Description
1 $then Then - required
2 $else Else - optional
IfZ($then, $else)
If the zero is set then execute the then body else the else body
Parameter Description
1 $then Then - required
2 $else Else - optional
IfLt($then, $else)
If less than execute the then body else the else body
Parameter Description
1 $then Then - required
2 $else Else - optional
IfLe($then, $else)
If less than or equal execute the then body else the else body
Parameter Description
1 $then Then - required
2 $else Else - optional
IfGt($then, $else)
If greater than execute the then body else the else body
Parameter Description
1 $then Then - required
2 $else Else - optional
IfGe($then, $else)
If greater than or equal execute the then body else the else body
Parameter Description
1 $then Then - required
2 $else Else - optional
For($body, $register, $limit, $increment)
For - iterate the body as long as register is less than limit incrementing by increment each time
Parameter Description
1 $body Body
2 $register Register
3 $limit Limit on loop
4 $increment Increment on each iteration
Example:
For # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
{PrintOutRegisterInHex rax
} rax, 16, 1;
my $r = Assemble;
ok $r =~ m(( 0000){3} 0000)i;
ok $r =~ m(( 0000){3} 000F)i;
ForIn($full, $last, $register, $limit, $increment)
For - iterate the full body as long as register plus increment is less than than limit incrementing by increment each time then increment the last body for the last non full block.
Parameter Description
1 $full Body for full block
2 $last Body for last block
3 $register Register
4 $limit Limit on loop
5 $increment Increment on each iteration
ForEver($body)
Iterate for ever
Parameter Description
1 $body Body to iterate
Macro($body, %options)
Create a sub with optional parameters name=> the name of the subroutine so it can be reused rather than regenerated, comment=> a comment describing the sub
Parameter Description
1 $body Body
2 %options Options.
Subroutine($body, %options)
Create a subroutine that can be called in assembler code
Parameter Description
1 $body Body
2 %options Options.
Nasm::X86::Sub::call($sub, @parameters)
Call a sub passing it some parameters
Parameter Description
1 $sub Subroutine descriptor
2 @parameters Parameter variables
cr($body, @registers)
Call a subroutine with a reordering of the registers.
Parameter Description
1 $body Code to execute with reordered registers
2 @registers Registers to reorder
Comment(@comment)
Insert a comment into the assembly code
Parameter Description
1 @comment Text of comment
Example:
Comment "Print a string from memory"; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $s = "Hello World";
Mov rax, Rs($s);
Mov rdi, length $s;
PrintOutMemory;
ok Assemble =~ m(Hello World);
DComment(@comment)
Insert a comment into the data segment
Parameter Description
1 @comment Text of comment
RComment(@comment)
Insert a comment into the read only data segment
Parameter Description
1 @comment Text of comment
PrintNL($channel)
Print a new line to stdout or stderr
Parameter Description
1 $channel Channel to write on
PrintErrNL()
Print a new line to stderr
PrintOutNL()
Print a new line to stderr
Example:
my $q = Rs('abababab');
Mov(rax, "[$q]");
PrintOutString "rax: ";
PrintOutRaxInHex;
PrintOutNL; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Xor rax, rax;
PrintOutString "rax: ";
PrintOutRaxInHex;
PrintOutNL; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble =~ m(rax: 6261 6261 6261 6261.*rax: 0000 0000 0000 0000)s;
PrintString($channel, @string)
Print a constant string to the specified channel
Parameter Description
1 $channel Channel
2 @string Strings
PrintErrString(@string)
Print a constant string to stderr.
Parameter Description
1 @string String
PrintOutString(@string)
Print a constant string to stdout.
Parameter Description
1 @string String
PrintErrStringNL(@string)
Print a constant string followed by a new line to stderr
Parameter Description
1 @string Strings
Example:
PrintOutStringNL "Hello World";
PrintOutStringNL "Hello
World";
PrintErrStringNL "Hello World"; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble(debug => 0, eq => <<END);
Hello World
Hello
World
END
PrintOutStringNL(@string)
Print a constant string followed by a new line to stdout
Parameter Description
1 @string Strings
Example:
PrintOutStringNL "Hello World"; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutStringNL "Hello
World"; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintErrStringNL "Hello World";
ok Assemble(debug => 0, eq => <<END);
Hello World
Hello
World
END
PrintRaxInHex($channel, $end)
Write the content of register rax in hexadecimal in big endian notation to the specified channel
Parameter Description
1 $channel Channel
2 $end Optional end byte
PrintErrRaxInHex()
Write the content of register rax in hexadecimal in big endian notation to stderr
PrintOutRaxInHex()
Write the content of register rax in hexadecimal in big endian notation to stderr
Example:
my $q = Rs('abababab');
Mov(rax, "[$q]");
PrintOutString "rax: ";
PrintOutRaxInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
Xor rax, rax;
PrintOutString "rax: ";
PrintOutRaxInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
ok Assemble =~ m(rax: 6261 6261 6261 6261.*rax: 0000 0000 0000 0000)s;
PrintOutRaxInReverseInHex()
Write the content of register rax to stderr in hexadecimal in little endian notation
Example:
Mov rax, 0x07654321;
Shl rax, 32;
Or rax, 0x07654321;
PushR rax;
PrintOutRaxInHex;
PrintOutNL;
PrintOutRaxInReverseInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
KeepFree rax;
Mov rax, rsp;
Mov rdi, 8;
PrintOutMemoryInHex;
PrintOutNL;
PopR rax;
KeepFree rax, rdi;
Mov rax, 4096;
PushR rax;
Mov rax, rsp;
Mov rdi, 8;
PrintOutMemoryInHex;
PrintOutNL;
PopR rax;
is_deeply Assemble, <<END;
0765 4321 0765 4321
2143 6507 2143 6507
2143 6507 2143 6507
0010 0000 0000 0000
END
PrintRegisterInHex($channel, @r)
Print the named registers as hex strings
Parameter Description
1 $channel Channel to print on
2 @r Names of the registers to print
PrintErrRegisterInHex(@r)
Print the named registers as hex strings on stderr
Parameter Description
1 @r Names of the registers to print
PrintOutRegisterInHex(@r)
Print the named registers as hex strings on stdout
Parameter Description
1 @r Names of the registers to print
Example:
my $q = Rs(('a'..'p')x4);
Mov r8,"[$q]";
PrintOutRegisterInHex r8; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble =~ m(r8: 6867 6665 6463 6261)s;
PrintOutRegistersInHex()
Print the general purpose registers in hex
Example:
my $q = Rs('abababab');
Mov(rax, 1);
Mov(rbx, 2);
Mov(rcx, 3);
Mov(rdx, 4);
Mov(r8, 5);
Lea r9, "[rax+rbx]";
PrintOutRegistersInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $r = Assemble;
ok $r =~ m( r8: 0000 0000 0000 0005.* r9: 0000 0000 0000 0003.*rax: 0000 0000 0000 0001)s;
ok $r =~ m(rbx: 0000 0000 0000 0002.*rcx: 0000 0000 0000 0003.*rdx: 0000 0000 0000 0004)s;
PrintErrZF()
Print the zero flag without disturbing it on stderr
PrintOutZF()
Print the zero flag without disturbing it on stdout
Example:
SetZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ClearZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
SetZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
SetZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ClearZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble =~ m(ZF=1.*ZF=0.*ZF=1.*ZF=1.*ZF=0)s;
Variables
Variable definitions and operations
Scopes
Each variable is contained in a scope in an effort to detect references to out of scope variables
Scope($name)
Create and stack a new scope and continue with it as the current scope
Parameter Description
1 $name Scope name
Example:
if (1)
{my $start = Scope(start); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $s1 = Scope(s1); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $s2 = Scope(s2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply $s2->depth, 2;
is_deeply $s2->name, q(s2);
ScopeEnd;
my $t1 = Scope(t1); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $t2 = Scope(t2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply $t1->depth, 2;
is_deeply $t1->name, q(t1);
is_deeply $t2->depth, 3;
is_deeply $t2->name, q(t2);
ok $s1->currentlyVisible;
ok !$s2->currentlyVisible;
ok $s1->contains($t2);
ok !$s2->contains($t2);
ScopeEnd;
is_deeply $s1->depth, 1;
is_deeply $s1->name, q(s1);
ScopeEnd;
}
ScopeEnd()
End the current scope and continue with the containing parent scope
Example:
if (1)
{my $start = Scope(start);
my $s1 = Scope(s1);
my $s2 = Scope(s2);
is_deeply $s2->depth, 2;
is_deeply $s2->name, q(s2);
ScopeEnd; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $t1 = Scope(t1);
my $t2 = Scope(t2);
is_deeply $t1->depth, 2;
is_deeply $t1->name, q(t1);
is_deeply $t2->depth, 3;
is_deeply $t2->name, q(t2);
ok $s1->currentlyVisible;
ok !$s2->currentlyVisible;
ok $s1->contains($t2);
ok !$s2->contains($t2);
ScopeEnd; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply $s1->depth, 1;
is_deeply $s1->name, q(s1);
ScopeEnd; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
}
Nasm::X86::Scope::contains($parent, $child)
Check that the named parent scope contains the specified child scope. If no child scope is supplied we use the current scope to check that the parent scope is currently visible
Parameter Description
1 $parent Parent scope
2 $child Child scope
Nasm::X86::Scope::currentlyVisible($scope)
Check that the named parent scope is currently visible
Parameter Description
1 $scope Scope to check for visibility
Definitions
Variable definitions
Variable($size, $name, $expr, %options)
Create a new variable with the specified size and name initialized via an expression
Parameter Description
1 $size Size as a power of 2
2 $name Name of variable
3 $expr Optional expression initializing variable
4 %options Options
Vb($name, $expr, %options)
Define a byte variable
Parameter Description
1 $name Name of variable
2 $expr Initializing expression
3 %options Options
Vw($name, $expr, %options)
Define a word variable
Parameter Description
1 $name Name of variable
2 $expr Initializing expression
3 %options Options
Vd($name, $expr, %options)
Define a double word variable
Parameter Description
1 $name Name of variable
2 $expr Initializing expression
3 %options Options
Vq($name, $expr, %options)
Define a quad variable
Parameter Description
1 $name Name of variable
2 $expr Initializing expression
3 %options Options
Cq($name, $expr, %options)
Define a quad constant
Parameter Description
1 $name Name of variable
2 $expr Initializing expression
3 %options Options
VxyzInit($var, @expr)
Initialize an xyz register from general purpose registers
Parameter Description
1 $var Variable
2 @expr Initializing general purpose registers or undef
Vx($name, @expr)
Define an xmm variable
Parameter Description
1 $name Name of variable
2 @expr Initializing expression
Vy($name, @expr)
Define an ymm variable
Parameter Description
1 $name Name of variable
2 @expr Initializing expression
Vz($name, @expr)
Define an zmm variable
Parameter Description
1 $name Name of variable
2 @expr Initializing expression
Vr($name, $size)
Define a reference variable
Parameter Description
1 $name Name of variable
2 $size Variable being referenced
Operations
Variable operations
Nasm::X86::Variable::address($left, $offset)
Get the address of a variable with an optional offset
Parameter Description
1 $left Left variable
2 $offset Optional offset
Nasm::X86::Variable::copy($left, $right)
Copy one variable into another
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::clone($var)
Clone a variable to create a new variable
Parameter Description
1 $var Variable to clone
Nasm::X86::Variable::copyAddress($left, $right)
Copy a reference to a variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::equals($op, $left, $right)
Equals operator
Parameter Description
1 $op Operator
2 $left Left variable
3 $right Right variable
Nasm::X86::Variable::assign($left, $op, $right)
Assign to the left hand side the value of the right hand side
Parameter Description
1 $left Left variable
2 $op Operator
3 $right Right variable
Nasm::X86::Variable::plusAssign($left, $right)
Implement plus and assign
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::minusAssign($left, $right)
Implement minus and assign
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::arithmetic($op, $name, $left, $right)
Return a variable containing the result of an arithmetic operation on the left hand and right hand side variables
Parameter Description
1 $op Operator
2 $name Operator name
3 $left Left variable
4 $right Right variable
Nasm::X86::Variable::add($left, $right)
Add the right hand variable to the left hand variable and return the result as a new variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::sub($left, $right)
Subtract the right hand variable from the left hand variable and return the result as a new variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::times($left, $right)
Multiply the left hand variable by the right hand variable and return the result as a new variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::division($op, $left, $right)
Return a variable containing the result or the remainder that occurs when the left hand side is divided by the right hand side
Parameter Description
1 $op Operator
2 $left Left variable
3 $right Right variable
Nasm::X86::Variable::divide($left, $right)
Divide the left hand variable by the right hand variable and return the result as a new variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::mod($left, $right)
Divide the left hand variable by the right hand variable and return the remainder as a new variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::boolean($sub, $op, $left, $right)
Combine the left hand variable with the right hand variable via a boolean operator
Parameter Description
1 $sub Operator
2 $op Operator name
3 $left Left variable
4 $right Right variable
Nasm::X86::Variable::eq($left, $right)
Check whether the left hand variable is equal to the right hand variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::ne($left, $right)
Check whether the left hand variable is not equal to the right hand variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::ge($left, $right)
Check whether the left hand variable is greater than or equal to the right hand variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::gt($left, $right)
Check whether the left hand variable is greater than the right hand variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::le($left, $right)
Check whether the left hand variable is less than or equal to the right hand variable
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::lt($left, $right)
Check whether the left hand variable is less than the right hand variable
Parameter Description
1 $left Left variable
2 $right Right variable
Print variables
Print the values of variables or the memory addressed by them
Nasm::X86::Variable::dump($left, $channel, $newLine, $title1, $title2)
Dump the value of a variable to the specified channel adding an optional title and new line if requested
Parameter Description
1 $left Left variable
2 $channel Channel
3 $newLine New line required
4 $title1 Optional leading title
5 $title2 Optional trailing title
Example:
my $a = Vq(a, 3); $a->outNL;
my $b = Vq(b, 2); $b->outNL;
my $c = $a + $b; $c->outNL;
my $d = $c - $a; $d->outNL;
my $e = $d == $b; $e->outNL;
my $f = $d != $b; $f->outNL;
my $g = $a * $b; $g->outNL;
my $h = $g / $b; $h->outNL;
my $i = $a % $b; $i->outNL;
If ($a == 3, sub{PrintOutStringNL "a == 3"});
++$a; $a->outNL;
--$a; $a->outNL;
ok Assemble(debug => 0, eq => <<END);
a: 0000 0000 0000 0003
b: 0000 0000 0000 0002
(a add b): 0000 0000 0000 0005
((a add b) sub a): 0000 0000 0000 0002
(((a add b) sub a) eq b): 0000 0000 0000 0001
(((a add b) sub a) ne b): 0000 0000 0000 0000
(a times b): 0000 0000 0000 0006
((a times b) / b): 0000 0000 0000 0003
(a % b): 0000 0000 0000 0001
a == 3
a: 0000 0000 0000 0004
a: 0000 0000 0000 0003
END
Nasm::X86::Variable::err($left, $title1, $title2)
Dump the value of a variable on stderr
Parameter Description
1 $left Left variable
2 $title1 Optional leading title
3 $title2 Optional trailing title
Nasm::X86::Variable::out($left, $title1, $title2)
Dump the value of a variable on stdout
Parameter Description
1 $left Left variable
2 $title1 Optional leading title
3 $title2 Optional trailing title
Nasm::X86::Variable::errNL($left, $title1, $title2)
Dump the value of a variable on stderr and append a new line
Parameter Description
1 $left Left variable
2 $title1 Optional leading title
3 $title2 Optional trailing title
Nasm::X86::Variable::outNL($left, $title1, $title2)
Dump the value of a variable on stdout and append a new line
Parameter Description
1 $left Left variable
2 $title1 Optional leading title
3 $title2 Optional trailing title
Nasm::X86::Variable::debug($left)
Dump the value of a variable on stdout with an indication of where the dump came from
Parameter Description
1 $left Left variable
Nasm::X86::Variable::isRef($variable)
Check whether the specified variable is a reference to another variable
Parameter Description
1 $variable Variable
Nasm::X86::Variable::setReg($variable, $register, @registers)
Set the named registers from the content of the variable
Parameter Description
1 $variable Variable
2 $register Register to load
3 @registers Optional further registers to load
Nasm::X86::Variable::getReg($variable, $register, @registers)
Load the variable from the named registers
Parameter Description
1 $variable Variable
2 $register Register to load
3 @registers Optional further registers to load from
Nasm::X86::Variable::getConst($variable, $constant)
Load the variable from a constant in effect setting a variable to a specified value
Parameter Description
1 $variable Variable
2 $constant Constant to load
Nasm::X86::Variable::incDec($left, $op)
Increment or decrement a variable
Parameter Description
1 $left Left variable operator
2 $op Address of operator to perform inc or dec
Nasm::X86::Variable::inc($left)
Increment a variable
Parameter Description
1 $left Variable
Nasm::X86::Variable::dec($left)
Decrement a variable
Parameter Description
1 $left Variable
Nasm::X86::Variable::str($left)
The name of the variable
Parameter Description
1 $left Variable
Nasm::X86::Variable::min($left, $right)
Minimum of two variables
Parameter Description
1 $left Left variable
2 $right Right variable
Example:
my $a = Vq("a", 1);
my $b = Vq("b", 2);
my $c = $a->min($b);
my $d = $a->max($b);
$a->outNL;
$b->outNL;
$c->outNL;
$d->outNL;
is_deeply Assemble,<<END;
a: 0000 0000 0000 0001
b: 0000 0000 0000 0002
Minimum(a, b): 0000 0000 0000 0001
Maximum(a, b): 0000 0000 0000 0002
END
Nasm::X86::Variable::max($left, $right)
Maximum of two variables
Parameter Description
1 $left Left variable
2 $right Right variable
Example:
my $a = Vq("a", 1);
my $b = Vq("b", 2);
my $c = $a->min($b);
my $d = $a->max($b);
$a->outNL;
$b->outNL;
$c->outNL;
$d->outNL;
is_deeply Assemble,<<END;
a: 0000 0000 0000 0001
b: 0000 0000 0000 0002
Minimum(a, b): 0000 0000 0000 0001
Maximum(a, b): 0000 0000 0000 0002
END
Nasm::X86::Variable::and($left, $right)
And two variables
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::or($left, $right)
Or two variables
Parameter Description
1 $left Left variable
2 $right Right variable
Nasm::X86::Variable::setMask($start, $length, $mask)
Set the mask register to ones starting at the specified position for the specified length and zeroes elsewhere
Parameter Description
1 $start Variable containing start of mask
2 $length Variable containing length of mask
3 $mask Mask register
Example:
my $start = Vq("Start", 7);
my $length = Vq("Length", 3);
$start->setMask($length, k7);
PrintOutRegisterInHex k7;
is_deeply Assemble, <<END;
k7: 0000 0000 0000 0380
END
my $z = Vq('zero', 0);
my $o = Vq('one', 1);
my $t = Vq('two', 2);
$z->setMask($o, k7); PrintOutRegisterInHex k7;
$z->setMask($t, k6); PrintOutRegisterInHex k6;
$z->setMask($o+$t, k5); PrintOutRegisterInHex k5;
$o->setMask($o, k4); PrintOutRegisterInHex k4;
$o->setMask($t, k3); PrintOutRegisterInHex k3;
$o->setMask($o+$t, k2); PrintOutRegisterInHex k2;
$t->setMask($o, k1); PrintOutRegisterInHex k1;
$t->setMask($t, k0); PrintOutRegisterInHex k0;
ok Assemble(debug => 0, eq => <<END);
k7: 0000 0000 0000 0001
k6: 0000 0000 0000 0003
k5: 0000 0000 0000 0007
k4: 0000 0000 0000 0002
k3: 0000 0000 0000 0006
k2: 0000 0000 0000 000E
k1: 0000 0000 0000 0004
k0: 0000 0000 0000 000C
END
Nasm::X86::Variable::setMaskFirst($length, $mask)
Set the first bits in the specified mask register
Parameter Description
1 $length Variable containing length to set
2 $mask Mask register
Nasm::X86::Variable::setMaskBit($length, $mask)
Set a bit in the specified mask register retaining the other bits
Parameter Description
1 $length Variable containing bit position to set
2 $mask Mask register
Nasm::X86::Variable::clearMaskBit($length, $mask)
Clear a bit in the specified mask register retaining the other bits
Parameter Description
1 $length Variable containing bit position to clear
2 $mask Mask register
Nasm::X86::Variable::setZmm($source, $zmm, $offset, $length)
Load bytes from the memory addressed by specified source variable into the numbered zmm register at the offset in the specified offset moving the number of bytes in the specified variable
Parameter Description
1 $source Variable containing the address of the source
2 $zmm Number of zmm to load
3 $offset Variable containing offset in zmm to move to
4 $length Variable containing length of move
Example:
my $s = Rb(0..128);
my $source = Vq(Source, $s);
if (1) # First block
{my $offset = Vq(Offset, 7);
my $length = Vq(Length, 3);
$source->setZmm(0, $offset, $length);
}
if (1) # Second block
{my $offset = Vq(Offset, 33);
my $length = Vq(Length, 12);
$source->setZmm(0, $offset, $length);
}
PrintOutRegisterInHex zmm0;
is_deeply Assemble, <<END;
zmm0: 0000 0000 0000 0000 0000 0000 0000 0000 0000 000B 0A09 0807 0605 0403 0201 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0201 0000 0000 0000 0000
END
my $a = Vz a, Rb((map {"0x${_}0"} 0..9, 'a'..'f')x4);
my $b = Vz b, Rb((map {"0x0${_}"} 0..9, 'a'..'f')x4);
$a ->loadZmm(0); # Show variable in zmm0
$b ->loadZmm(1); # Show variable in zmm1
($a + $b)->loadZmm(2); # Add bytes and show in zmm2
($a - $b)->loadZmm(3); # Subtract bytes and show in zmm3
PrintOutRegisterInHex "zmm$_" for 0..3;
is_deeply Assemble, <<END;
zmm0: F0E0 D0C0 B0A0 9080 7060 5040 3020 1000 F0E0 D0C0 B0A0 9080 7060 5040 3020 1000 F0E0 D0C0 B0A0 9080 7060 5040 3020 1000 F0E0 D0C0 B0A0 9080 7060 5040 3020 1000
zmm1: 0F0E 0D0C 0B0A 0908 0706 0504 0302 0100 0F0E 0D0C 0B0A 0908 0706 0504 0302 0100 0F0E 0D0C 0B0A 0908 0706 0504 0302 0100 0F0E 0D0C 0B0A 0908 0706 0504 0302 0100
zmm2: FFEE DDCC BBAA 9988 7766 5544 3322 1100 FFEE DDCC BBAA 9988 7766 5544 3322 1100 FFEE DDCC BBAA 9988 7766 5544 3322 1100 FFEE DDCC BBAA 9988 7766 5544 3322 1100
zmm3: E1D2 C3B4 A596 8778 695A 4B3C 2D1E 0F00 E1D2 C3B4 A596 8778 695A 4B3C 2D1E 0F00 E1D2 C3B4 A596 8778 695A 4B3C 2D1E 0F00 E1D2 C3B4 A596 8778 695A 4B3C 2D1E 0F00
END
Nasm::X86::Variable::loadZmm($source, $zmm)
Load bytes from the memory addressed by the specified source variable into the numbered zmm register.
Parameter Description
1 $source Variable containing the address of the source
2 $zmm Number of zmm to get
Nasm::X86::Variable::saveZmm2222($target, $zmm)
Save bytes into the memory addressed by the target variable from the numbered zmm register.
Parameter Description
1 $target Variable containing the address of the source
2 $zmm Number of zmm to put
getBwdqFromMm($size, $mm, $offset)
Get the numbered byte|word|double word|quad word from the numbered zmm register and return it in a variable
Parameter Description
1 $size Size of get
2 $mm Register
3 $offset Offset in bytes either as a constant or as a variable
getBFromXmm($xmm, $offset)
Get the byte from the numbered xmm register and return it in a variable
Parameter Description
1 $xmm Numbered xmm
2 $offset Offset in bytes
getWFromXmm($xmm, $offset)
Get the word from the numbered xmm register and return it in a variable
Parameter Description
1 $xmm Numbered xmm
2 $offset Offset in bytes
getDFromXmm($xmm, $offset)
Get the double word from the numbered xmm register and return it in a variable
Parameter Description
1 $xmm Numbered xmm
2 $offset Offset in bytes
getQFromXmm($xmm, $offset)
Get the quad word from the numbered xmm register and return it in a variable
Parameter Description
1 $xmm Numbered xmm
2 $offset Offset in bytes
getBFromZmm($zmm, $offset)
Get the byte from the numbered zmm register and return it in a variable
Parameter Description
1 $zmm Numbered zmm
2 $offset Offset in bytes
getWFromZmm($zmm, $offset)
Get the word from the numbered zmm register and return it in a variable
Parameter Description
1 $zmm Numbered zmm
2 $offset Offset in bytes
getDFromZmm($zmm, $offset)
Get the double word from the numbered zmm register and return it in a variable
Parameter Description
1 $zmm Numbered zmm
2 $offset Offset in bytes
Example:
my $s = Rb(0..8);
my $c = Vq("Content", "[$s]");
$c->putBIntoZmm(0, 4);
$c->putWIntoZmm(0, 6);
$c->putDIntoZmm(0, 10);
$c->putQIntoZmm(0, 16);
PrintOutRegisterInHex zmm0;
getBFromZmm(0, 12)->outNL;
getWFromZmm(0, 12)->outNL;
getDFromZmm(0, 12)->outNL; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
getQFromZmm(0, 12)->outNL;
is_deeply Assemble, <<END;
zmm0: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0706 0504 0302 0100 0000 0302 0100 0000 0100 0000 0000 0000
b at offset 12 in zmm0: 0000 0000 0000 0002
w at offset 12 in zmm0: 0000 0000 0000 0302
d at offset 12 in zmm0: 0000 0000 0000 0302
q at offset 12 in zmm0: 0302 0100 0000 0302
END
getQFromZmm($zmm, $offset)
Get the quad word from the numbered zmm register and return it in a variable
Parameter Description
1 $zmm Numbered zmm
2 $offset Offset in bytes
Nasm::X86::Variable::getBFromZmm($variable, $zmm, $offset)
Get the byte from the numbered zmm register and put it in a variable
Parameter Description
1 $variable Variable
2 $zmm Numbered zmm
3 $offset Offset in bytes
Nasm::X86::Variable::getWFromZmm($variable, $zmm, $offset)
Get the word from the numbered zmm register and put it in a variable
Parameter Description
1 $variable Variable
2 $zmm Numbered zmm
3 $offset Offset in bytes
Nasm::X86::Variable::getDFromZmm($variable, $zmm, $offset)
Get the double word from the numbered zmm register and put it in a variable
Parameter Description
1 $variable Variable
2 $zmm Numbered zmm
3 $offset Offset in bytes
Nasm::X86::Variable::getQFromZmm($variable, $zmm, $offset)
Get the quad word from the numbered zmm register and put it in a variable
Parameter Description
1 $variable Variable
2 $zmm Numbered zmm
3 $offset Offset in bytes
Nasm::X86::Variable::putBwdqIntoMm($content, $size, $mm, $offset)
Place the value of the content variable at the byte|word|double word|quad word in the numbered zmm register
Parameter Description
1 $content Variable with content
2 $size Size of put
3 $mm Numbered zmm
4 $offset Offset in bytes
Nasm::X86::Variable::putBIntoXmm($content, $xmm, $offset)
Place the value of the content variable at the byte in the numbered xmm register
Parameter Description
1 $content Variable with content
2 $xmm Numbered xmm
3 $offset Offset in bytes
Nasm::X86::Variable::putWIntoXmm($content, $xmm, $offset)
Place the value of the content variable at the word in the numbered xmm register
Parameter Description
1 $content Variable with content
2 $xmm Numbered xmm
3 $offset Offset in bytes
Nasm::X86::Variable::putDIntoXmm($content, $xmm, $offset)
Place the value of the content variable at the double word in the numbered xmm register
Parameter Description
1 $content Variable with content
2 $xmm Numbered xmm
3 $offset Offset in bytes
Nasm::X86::Variable::putQIntoXmm($content, $xmm, $offset)
Place the value of the content variable at the quad word in the numbered xmm register
Parameter Description
1 $content Variable with content
2 $xmm Numbered xmm
3 $offset Offset in bytes
Nasm::X86::Variable::putBIntoZmm($content, $zmm, $offset)
Place the value of the content variable at the byte in the numbered zmm register
Parameter Description
1 $content Variable with content
2 $zmm Numbered zmm
3 $offset Offset in bytes
Nasm::X86::Variable::putWIntoZmm($content, $zmm, $offset)
Place the value of the content variable at the word in the numbered zmm register
Parameter Description
1 $content Variable with content
2 $zmm Numbered zmm
3 $offset Offset in bytes
Nasm::X86::Variable::putDIntoZmm($content, $zmm, $offset)
Place the value of the content variable at the double word in the numbered zmm register
Parameter Description
1 $content Variable with content
2 $zmm Numbered zmm
3 $offset Offset in bytes
Example:
my $s = Rb(0..8);
my $c = Vq("Content", "[$s]");
$c->putBIntoZmm(0, 4);
$c->putWIntoZmm(0, 6);
$c->putDIntoZmm(0, 10);
$c->putQIntoZmm(0, 16);
PrintOutRegisterInHex zmm0;
getBFromZmm(0, 12)->outNL;
getWFromZmm(0, 12)->outNL;
getDFromZmm(0, 12)->outNL;
getQFromZmm(0, 12)->outNL;
is_deeply Assemble, <<END;
zmm0: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0706 0504 0302 0100 0000 0302 0100 0000 0100 0000 0000 0000
b at offset 12 in zmm0: 0000 0000 0000 0002
w at offset 12 in zmm0: 0000 0000 0000 0302
d at offset 12 in zmm0: 0000 0000 0000 0302
q at offset 12 in zmm0: 0302 0100 0000 0302
END
Nasm::X86::Variable::putQIntoZmm($content, $zmm, $offset)
Place the value of the content variable at the quad word in the numbered zmm register
Parameter Description
1 $content Variable with content
2 $zmm Numbered zmm
3 $offset Offset in bytes
Broadcast
Broadcast from a variable into a zmm
Nasm::X86::Variable::zBroadCastD($variable, $zmm)
Broadcast a double word in a variable into the numbered zmm.
Parameter Description
1 $variable Variable containing value to broadcast
2 $zmm Numbered zmm to broadcast to
Stack
Push and pop variables to and from the stack
Nasm::X86::Variable::push($variable)
Push a variable onto the stack
Parameter Description
1 $variable Variable
Nasm::X86::Variable::pop($variable)
Pop a variable from the stack
Parameter Description
1 $variable Variable
Memory
Actions on memory described by variables
Nasm::X86::Variable::clearMemory($address, $size)
Clear the memory described in this variable
Parameter Description
1 $address Address of memory to clear
2 $size Size of the memory to clear
Nasm::X86::Variable::copyMemory($target, $source, $size)
Copy from one block of memory to another
Parameter Description
1 $target Address of target
2 $source Address of source
3 $size Length to copy
Nasm::X86::Variable::printMemoryInHexNL($address, $channel, $size)
Write the memory addressed by a variable to stdout or stderr
Parameter Description
1 $address Address of memory
2 $channel Channel to print on
3 $size Number of bytes to print
Nasm::X86::Variable::printErrMemoryInHexNL($address, $size)
Write the memory addressed by a variable to stderr
Parameter Description
1 $address Address of memory
2 $size Number of bytes to print
Nasm::X86::Variable::printOutMemoryInHexNL($address, $size)
Write the memory addressed by a variable to stdout
Parameter Description
1 $address Address of memory
2 $size Number of bytes to print
Nasm::X86::Variable::freeMemory($address, $size)
Free the memory addressed by this variable for the specified length
Parameter Description
1 $address Address of memory to free
2 $size Size of the memory to free
Example:
my $N = Vq(size, 2048);
my $q = Rs('a'..'p');
AllocateMemory($N, my $address = Vq(address));
Vmovdqu8 xmm0, "[$q]";
$address->setReg(rax);
Vmovdqu8 "[rax]", xmm0;
Mov rdi, 16;
PrintOutMemory;
PrintOutNL;
FreeMemory(address => $address, size=> $N);
ok Assemble(eq => <<END);
abcdefghijklmnop
END
Nasm::X86::Variable::allocateMemory($size)
Allocate the specified amount of memory via mmap and return its address
Parameter Description
1 $size Size
Structured Programming with variables
Structured programming operations driven off variables.
Nasm::X86::Variable::for($limit, $body)
Iterate the body limit times.
Parameter Description
1 $limit Limit
2 $body Body
Example:
Vq(limit,10)->for(sub
{my ($i, $start, $next, $end) = @_;
$i->outNL;
});
is_deeply Assemble, <<END;
index: 0000 0000 0000 0000
index: 0000 0000 0000 0001
index: 0000 0000 0000 0002
index: 0000 0000 0000 0003
index: 0000 0000 0000 0004
index: 0000 0000 0000 0005
index: 0000 0000 0000 0006
index: 0000 0000 0000 0007
index: 0000 0000 0000 0008
index: 0000 0000 0000 0009
END
Stack
Manage data on the stack
Push, Pop, Peek
Generic versions of push, pop, peek
PopR(@r)
Pop registers from the stack
Parameter Description
1 @r Register
Example:
Mov rax, 0x11111111;
Mov rbx, 0x22222222;
PushR my @save = (rax, rbx);
Mov rax, 0x33333333;
PopR @save; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
is_deeply Assemble,<<END;
rax: 0000 0000 1111 1111
rbx: 0000 0000 2222 2222
END
PopEax()
We cannot pop a double word from the stack in 64 bit long mode using pop so we improvise
Example:
Mov r14, 0;
Kmovq k0, r14;
KeepFree r14;
Ktestq k0, k0;
IfZ {PrintOutStringNL "0 & 0 == 0"};
PrintOutZF;
LoadConstantIntoMaskRegister k1, 1;
Ktestq k1, k1;
IfNz {PrintOutStringNL "1 & 1 != 0"};
PrintOutZF;
LoadConstantIntoMaskRegister k2, eval "0b".(('1'x4).('0'x4))x2;
PrintOutRegisterInHex k0, k1, k2;
Mov r15, 0x89abcdef;
Mov r14, 0x01234567;
Shl r14, 32;
Or r15, r14;
Push r15;
Push r15;
KeepFree r15;
PopEax; PrintRaxInHex($stdout, 3); PrintOutNL; KeepFree rax; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $a = Vq('aaaa');
$a->pop;
$a->push;
$a->outNL;
PopEax; PrintRaxInHex($stdout, 3); PrintOutNL; KeepFree rax; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble(debug => 0, eq => <<END);
0 & 0 == 0
ZF=1
1 & 1 != 0
ZF=0
k0: 0000 0000 0000 0000
k1: 0000 0000 0000 0001
k2: 0000 0000 0000 F0F0
89AB CDEF
aaaa: 89AB CDEF 0123 4567
0123 4567
END
PeekR($r)
Peek at register on stack
Parameter Description
1 $r Register
Declarations
Declare variables and structures
Structures
Declare a structure
Structure()
Create a structure addressed by a register
Nasm::X86::Structure::field($structure, $length, $comment)
Add a field of the specified length with an optional comment
Parameter Description
1 $structure Structure data descriptor
2 $length Length of data
3 $comment Optional comment
Nasm::X86::StructureField::addr($field, $register)
Address a field in a structure by either the default register or the named register
Parameter Description
1 $field Field
2 $register Optional address register else rax
All8Structure($N)
Create a structure consisting of 8 byte fields
Parameter Description
1 $N Number of variables required
Stack Frame
Declare local variables in a frame on the stack
LocalData()
Map local data
Nasm::X86::LocalData::start($local)
Start a local data area on the stack
Parameter Description
1 $local Local data descriptor
Nasm::X86::LocalData::free($local)
Free a local data area on the stack
Parameter Description
1 $local Local data descriptor
Nasm::X86::LocalData::variable($local, $length, $comment)
Add a local variable
Parameter Description
1 $local Local data descriptor
2 $length Length of data
3 $comment Optional comment
Nasm::X86::LocalVariable::stack($variable)
Address a local variable on the stack
Parameter Description
1 $variable Variable
Nasm::X86::LocalData::allocate8($local, @comments)
Add some 8 byte local variables and return an array of variable definitions
Parameter Description
1 $local Local data descriptor
2 @comments Optional comment
AllocateAll8OnStack($N)
Create a local data descriptor consisting of the specified number of 8 byte local variables and return an array: (local data descriptor, variable definitions...)
Parameter Description
1 $N Number of variables required
Operating system
Interacting with the operating system.
Processes
Create and manage processes
Fork()
Fork
Example:
Fork; # Fork # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Test rax,rax;
IfNz # Parent
{Mov rbx, rax;
WaitPid;
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
KeepFree rax;
GetPid; # Pid of parent as seen in parent
Mov rcx,rax;
PrintOutRegisterInHex rcx;
}
sub # Child
{Mov r8,rax;
PrintOutRegisterInHex r8;
KeepFree rax;
GetPid; # Child pid as seen in child
Mov r9,rax;
PrintOutRegisterInHex r9;
KeepFree rax;
GetPPid; # Parent pid as seen in child
Mov r10,rax;
PrintOutRegisterInHex r10;
};
my $r = Assemble;
# r8: 0000 0000 0000 0000 #1 Return from fork as seen by child
# r9: 0000 0000 0003 0C63 #2 Pid of child
# r10: 0000 0000 0003 0C60 #3 Pid of parent from child
# rax: 0000 0000 0003 0C63 #4 Return from fork as seen by parent
# rbx: 0000 0000 0003 0C63 #5 Wait for child pid result
# rcx: 0000 0000 0003 0C60 #6 Pid of parent
if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
{ok $2 eq $4;
ok $2 eq $5;
ok $3 eq $6;
ok $2 gt $6;
}
GetPid()
Get process identifier
Example:
Fork; # Fork
Test rax,rax;
IfNz # Parent
{Mov rbx, rax;
WaitPid;
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
KeepFree rax;
GetPid; # Pid of parent as seen in parent # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rcx,rax;
PrintOutRegisterInHex rcx;
}
sub # Child
{Mov r8,rax;
PrintOutRegisterInHex r8;
KeepFree rax;
GetPid; # Child pid as seen in child # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov r9,rax;
PrintOutRegisterInHex r9;
KeepFree rax;
GetPPid; # Parent pid as seen in child
Mov r10,rax;
PrintOutRegisterInHex r10;
};
my $r = Assemble;
# r8: 0000 0000 0000 0000 #1 Return from fork as seen by child
# r9: 0000 0000 0003 0C63 #2 Pid of child
# r10: 0000 0000 0003 0C60 #3 Pid of parent from child
# rax: 0000 0000 0003 0C63 #4 Return from fork as seen by parent
# rbx: 0000 0000 0003 0C63 #5 Wait for child pid result
# rcx: 0000 0000 0003 0C60 #6 Pid of parent
if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
{ok $2 eq $4;
ok $2 eq $5;
ok $3 eq $6;
ok $2 gt $6;
}
GetPidInHex()
Get process identifier in hex as 8 zero terminated bytes in rax
Example:
GetPidInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
ok Assemble =~ m(rax: 00);
GetPPid()
Get parent process identifier
Example:
Fork; # Fork
Test rax,rax;
IfNz # Parent
{Mov rbx, rax;
WaitPid;
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
KeepFree rax;
GetPid; # Pid of parent as seen in parent
Mov rcx,rax;
PrintOutRegisterInHex rcx;
}
sub # Child
{Mov r8,rax;
PrintOutRegisterInHex r8;
KeepFree rax;
GetPid; # Child pid as seen in child
Mov r9,rax;
PrintOutRegisterInHex r9;
KeepFree rax;
GetPPid; # Parent pid as seen in child # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov r10,rax;
PrintOutRegisterInHex r10;
};
my $r = Assemble;
# r8: 0000 0000 0000 0000 #1 Return from fork as seen by child
# r9: 0000 0000 0003 0C63 #2 Pid of child
# r10: 0000 0000 0003 0C60 #3 Pid of parent from child
# rax: 0000 0000 0003 0C63 #4 Return from fork as seen by parent
# rbx: 0000 0000 0003 0C63 #5 Wait for child pid result
# rcx: 0000 0000 0003 0C60 #6 Pid of parent
if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
{ok $2 eq $4;
ok $2 eq $5;
ok $3 eq $6;
ok $2 gt $6;
}
GetUid()
Get userid of current process
Example:
GetUid; # Userid # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
my $r = Assemble;
ok $r =~ m(rax:( 0000){3});
WaitPid()
Wait for the pid in rax to complete
Example:
Fork; # Fork
Test rax,rax;
IfNz # Parent
{Mov rbx, rax;
WaitPid; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
KeepFree rax;
GetPid; # Pid of parent as seen in parent
Mov rcx,rax;
PrintOutRegisterInHex rcx;
}
sub # Child
{Mov r8,rax;
PrintOutRegisterInHex r8;
KeepFree rax;
GetPid; # Child pid as seen in child
Mov r9,rax;
PrintOutRegisterInHex r9;
KeepFree rax;
GetPPid; # Parent pid as seen in child
Mov r10,rax;
PrintOutRegisterInHex r10;
};
my $r = Assemble;
# r8: 0000 0000 0000 0000 #1 Return from fork as seen by child
# r9: 0000 0000 0003 0C63 #2 Pid of child
# r10: 0000 0000 0003 0C60 #3 Pid of parent from child
# rax: 0000 0000 0003 0C63 #4 Return from fork as seen by parent
# rbx: 0000 0000 0003 0C63 #5 Wait for child pid result
# rcx: 0000 0000 0003 0C60 #6 Pid of parent
if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
{ok $2 eq $4;
ok $2 eq $5;
ok $3 eq $6;
ok $2 gt $6;
}
ReadTimeStampCounter()
Read the time stamp counter and return the time in nanoseconds in rax
Example:
for(1..10)
{ReadTimeStampCounter; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
}
my @s = split /
/, Assemble;
my @S = sort @s;
is_deeply \@s, \@S;
Memory
Allocate and print memory
PrintMemoryInHex($channel)
Dump memory from the address in rax for the length in rdi on the specified channel. As this method prints in blocks of 8 up to 7 bytes will be missing from the end unless the length is a multiple of 8 .
Parameter Description
1 $channel Channel
PrintErrMemoryInHex()
Dump memory from the address in rax for the length in rdi on stderr
PrintOutMemoryInHex()
Dump memory from the address in rax for the length in rdi on stdout
Example:
Mov rax, 0x07654321;
Shl rax, 32;
Or rax, 0x07654321;
PushR rax;
PrintOutRaxInHex;
PrintOutNL;
PrintOutRaxInReverseInHex;
PrintOutNL;
KeepFree rax;
Mov rax, rsp;
Mov rdi, 8;
PrintOutMemoryInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
PopR rax;
KeepFree rax, rdi;
Mov rax, 4096;
PushR rax;
Mov rax, rsp;
Mov rdi, 8;
PrintOutMemoryInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
PopR rax;
is_deeply Assemble, <<END;
0765 4321 0765 4321
2143 6507 2143 6507
2143 6507 2143 6507
0010 0000 0000 0000
END
PrintErrMemoryInHexNL()
Dump memory from the address in rax for the length in rdi and then print a new line
PrintOutMemoryInHexNL()
Dump memory from the address in rax for the length in rdi and then print a new line
Example:
my $N = 256;
my $s = Rb 0..$N-1;
AllocateMemory(Cq(size, $N), my $a = Vq(address));
CopyMemory(Vq(source, $s), Vq(size, $N), target => $a);
AllocateMemory(Cq(size, $N), my $b = Vq(address));
CopyMemory(source => $a, target => $b, Cq(size, $N));
$b->setReg(rax);
Mov rdi, $N;
PrintOutMemoryInHexNL; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble(debug=>0, eq => <<END);
0001 0203 0405 06070809 0A0B 0C0D 0E0F1011 1213 1415 16171819 1A1B 1C1D 1E1F2021 2223 2425 26272829 2A2B 2C2D 2E2F3031 3233 3435 36373839 3A3B 3C3D 3E3F4041 4243 4445 46474849 4A4B 4C4D 4E4F5051 5253 5455 56575859 5A5B 5C5D 5E5F6061 6263 6465 66676869 6A6B 6C6D 6E6F7071 7273 7475 76777879 7A7B 7C7D 7E7F8081 8283 8485 86878889 8A8B 8C8D 8E8F9091 9293 9495 96979899 9A9B 9C9D 9E9FA0A1 A2A3 A4A5 A6A7A8A9 AAAB ACAD AEAFB0B1 B2B3 B4B5 B6B7B8B9 BABB BCBD BEBFC0C1 C2C3 C4C5 C6C7C8C9 CACB CCCD CECFD0D1 D2D3 D4D5 D6D7D8D9 DADB DCDD DEDFE0E1 E2E3 E4E5 E6E7E8E9 EAEB ECED EEEFF0F1 F2F3 F4F5 F6F7F8F9 FAFB FCFD FEFF
END
PrintMemory()
Print the memory addressed by rax for a length of rdi on the specified channel
Example:
ReadFile(Vq(file, Rs($0)), (my $s = Vq(size)), my $a = Vq(address)); # Read file
$a->setReg(rax); # Address of file in memory
$s->setReg(rdi); # Length of file in memory
PrintOutMemory; # Print contents of memory to stdout
my $r = Assemble; # Assemble and execute
ok stringMd5Sum($r) eq fileMd5Sum($0); # Output contains this file
PrintErrMemory()
Print the memory addressed by rax for a length of rdi on stderr
PrintOutMemory()
Print the memory addressed by rax for a length of rdi on stdout
Example:
Comment "Print a string from memory";
my $s = "Hello World";
Mov rax, Rs($s);
Mov rdi, length $s;
PrintOutMemory; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble =~ m(Hello World);
PrintErrMemoryNL()
Print the memory addressed by rax for a length of rdi followed by a new line on stderr
PrintOutMemoryNL()
Print the memory addressed by rax for a length of rdi followed by a new line on stdout
AllocateMemory(@variables)
Allocate the specified amount of memory via mmap and return its address
Parameter Description
1 @variables Parameters
Example:
my $N = Vq(size, 2048);
my $q = Rs('a'..'p');
AllocateMemory($N, my $address = Vq(address)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Vmovdqu8 xmm0, "[$q]";
$address->setReg(rax);
Vmovdqu8 "[rax]", xmm0;
Mov rdi, 16;
PrintOutMemory;
PrintOutNL;
FreeMemory(address => $address, size=> $N);
ok Assemble(eq => <<END);
abcdefghijklmnop
END
my $N = Vq(size, 4096); # Size of the initial allocation which should be one or more pages
AllocateMemory($N, my $A = Vq(address)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ClearMemory($N, $A);
$A->setReg(rax);
$N->setReg(rdi);
PrintOutMemoryInHexNL;
FreeMemory($N, $A);
ok Assemble(eq => <<END);
0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
END
my $N = 256;
my $s = Rb 0..$N-1;
AllocateMemory(Cq(size, $N), my $a = Vq(address)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
CopyMemory(Vq(source, $s), Vq(size, $N), target => $a);
AllocateMemory(Cq(size, $N), my $b = Vq(address)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
CopyMemory(source => $a, target => $b, Cq(size, $N));
$b->setReg(rax);
Mov rdi, $N;
PrintOutMemoryInHexNL;
ok Assemble(debug=>0, eq => <<END);
0001 0203 0405 06070809 0A0B 0C0D 0E0F1011 1213 1415 16171819 1A1B 1C1D 1E1F2021 2223 2425 26272829 2A2B 2C2D 2E2F3031 3233 3435 36373839 3A3B 3C3D 3E3F4041 4243 4445 46474849 4A4B 4C4D 4E4F5051 5253 5455 56575859 5A5B 5C5D 5E5F6061 6263 6465 66676869 6A6B 6C6D 6E6F7071 7273 7475 76777879 7A7B 7C7D 7E7F8081 8283 8485 86878889 8A8B 8C8D 8E8F9091 9293 9495 96979899 9A9B 9C9D 9E9FA0A1 A2A3 A4A5 A6A7A8A9 AAAB ACAD AEAFB0B1 B2B3 B4B5 B6B7B8B9 BABB BCBD BEBFC0C1 C2C3 C4C5 C6C7C8C9 CACB CCCD CECFD0D1 D2D3 D4D5 D6D7D8D9 DADB DCDD DEDFE0E1 E2E3 E4E5 E6E7E8E9 EAEB ECED EEEFF0F1 F2F3 F4F5 F6F7F8F9 FAFB FCFD FEFF
END
FreeMemory(@variables)
Free memory
Parameter Description
1 @variables Variables
Example:
my $N = Vq(size, 4096); # Size of the initial allocation which should be one or more pages
AllocateMemory($N, my $A = Vq(address));
ClearMemory($N, $A);
$A->setReg(rax);
$N->setReg(rdi);
PrintOutMemoryInHexNL;
FreeMemory($N, $A); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble(eq => <<END);
0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
END
ClearMemory(@variables)
Clear memory - the address of the memory is in rax, the length in rdi
Parameter Description
1 @variables Variables
Example:
my $N = Vq(size, 4096); # Size of the initial allocation which should be one or more pages
AllocateMemory($N, my $A = Vq(address));
ClearMemory($N, $A); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$A->setReg(rax);
$N->setReg(rdi);
PrintOutMemoryInHexNL;
FreeMemory($N, $A);
ok Assemble(eq => <<END);
0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
END
MaskMemory(@variables)
Write the specified byte into locations in the target mask that correspond to the locations in the source that contain the specified byte.
Parameter Description
1 @variables Variables
MaskMemoryInRange4(@variables)
Write the specified byte into locations in the target mask that correspond to the locations in the source that contain 4 bytes in the specified range.
Parameter Description
1 @variables Variables
CopyMemory(@variables)
Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Parameter Description
1 @variables Variables
Example:
my $s = Rb 0; Rb 1; Rw 2; Rd 3; Rq 4;
my $t = Db 0; Db 1; Dw 2; Dd 3; Dq 4;
Vmovdqu8 xmm0, "[$s]";
Vmovdqu8 xmm1, "[$t]";
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
Sub rsp, 16;
Mov rax, rsp; # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Mov rdi, 16;
Mov rsi, $s;
CopyMemory(Vq(source, rsi), Vq(target, rax), Vq(size, rdi)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutMemoryInHex;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(xmm1: 0000 0000 0000 0004 0000 0003 0002 0100);
ok $r =~ m(0001 0200 0300 00000400 0000 0000 0000);
my $N = 256;
my $s = Rb 0..$N-1;
AllocateMemory(Cq(size, $N), my $a = Vq(address));
CopyMemory(Vq(source, $s), Vq(size, $N), target => $a); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
AllocateMemory(Cq(size, $N), my $b = Vq(address));
CopyMemory(source => $a, target => $b, Cq(size, $N)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$b->setReg(rax);
Mov rdi, $N;
PrintOutMemoryInHexNL;
ok Assemble(debug=>0, eq => <<END);
0001 0203 0405 06070809 0A0B 0C0D 0E0F1011 1213 1415 16171819 1A1B 1C1D 1E1F2021 2223 2425 26272829 2A2B 2C2D 2E2F3031 3233 3435 36373839 3A3B 3C3D 3E3F4041 4243 4445 46474849 4A4B 4C4D 4E4F5051 5253 5455 56575859 5A5B 5C5D 5E5F6061 6263 6465 66676869 6A6B 6C6D 6E6F7071 7273 7475 76777879 7A7B 7C7D 7E7F8081 8283 8485 86878889 8A8B 8C8D 8E8F9091 9293 9495 96979899 9A9B 9C9D 9E9FA0A1 A2A3 A4A5 A6A7A8A9 AAAB ACAD AEAFB0B1 B2B3 B4B5 B6B7B8B9 BABB BCBD BEBFC0C1 C2C3 C4C5 C6C7C8C9 CACB CCCD CECFD0D1 D2D3 D4D5 D6D7D8D9 DADB DCDD DEDFE0E1 E2E3 E4E5 E6E7E8E9 EAEB ECED EEEFF0F1 F2F3 F4F5 F6F7F8F9 FAFB FCFD FEFF
END
Files
Interact with the operating system via files.
OpenRead()
Open a file, whose name is addressed by rax, for read and return the file descriptor in rax
Example:
Mov rax, Rs($0); # File to read
OpenRead; # Open file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
CloseFile; # Close file
PrintOutRegisterInHex rax;
KeepFree rax, rdi;
Mov rax, Rs(my $f = "zzzTemporaryFile.txt"); # File to write
OpenWrite; # Open file
CloseFile; # Close file
is_deeply Assemble, <<END; # Channel is now used for tracing
rax: 0000 0000 0000 0004
rax: 0000 0000 0000 0000
END
ok -e $f; # Created file
unlink $f;
OpenWrite()
Create the file named by the terminated string addressed by rax for write
Example:
Mov rax, Rs($0); # File to read
OpenRead; # Open file
PrintOutRegisterInHex rax;
CloseFile; # Close file
PrintOutRegisterInHex rax;
KeepFree rax, rdi;
Mov rax, Rs(my $f = "zzzTemporaryFile.txt"); # File to write
OpenWrite; # Open file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
CloseFile; # Close file
is_deeply Assemble, <<END; # Channel is now used for tracing
rax: 0000 0000 0000 0004
rax: 0000 0000 0000 0000
END
ok -e $f; # Created file
unlink $f;
CloseFile()
Close the file whose descriptor is in rax
Example:
Mov rax, Rs($0); # File to read
OpenRead; # Open file
PrintOutRegisterInHex rax;
CloseFile; # Close file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
KeepFree rax, rdi;
Mov rax, Rs(my $f = "zzzTemporaryFile.txt"); # File to write
OpenWrite; # Open file
CloseFile; # Close file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply Assemble, <<END; # Channel is now used for tracing
rax: 0000 0000 0000 0004
rax: 0000 0000 0000 0000
END
ok -e $f; # Created file
unlink $f;
StatSize()
Stat a file whose name is addressed by rax to get its size in rax
Example:
Mov rax, Rs($0); # File to stat
StatSize; # Stat the file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
my $r = Assemble =~ s( ) ()gsr;
if ($r =~ m(rax:([0-9a-f]{16}))is) # Compare file size obtained with that from fileSize()
{is_deeply $1, sprintf("%016X", fileSize($0));
}
ReadFile(@variables)
Read a file whose name is addressed by rax into memory. The address of the mapped memory and its length are returned in registers rax,rdi
Parameter Description
1 @variables Variables
Example:
ReadFile(Vq(file, Rs($0)), (my $s = Vq(size)), my $a = Vq(address)); # Read file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$a->setReg(rax); # Address of file in memory
$s->setReg(rdi); # Length of file in memory
PrintOutMemory; # Print contents of memory to stdout
my $r = Assemble; # Assemble and execute
ok stringMd5Sum($r) eq fileMd5Sum($0); # Output contains this file
executeFileViaBash(@variables)
Execute the file named in the byte string addressed by rax with bash
Parameter Description
1 @variables Variables
Example:
my $s = CreateByteString; # Create a string
$s->ql(<<END); # Write code to execute
#!/usr/bin/bash
whoami
ls -la
pwd
END
$s->write (my $f = Vq('file', Rs("zzz.sh"))); # Write code to a file
executeFileViaBash($f); # Execute the file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
unlinkFile ($f); # Delete the file
my $u = qx(whoami); chomp($u);
ok Assemble(emulator=>0) =~ m($u); # The Intel Software Development Emulator is way too slow on these operations.
unlinkFile(@variables)
Unlink the named file
Parameter Description
1 @variables Variables
Example:
my $s = CreateByteString; # Create a string
$s->ql(<<END); # Write code to execute
#!/usr/bin/bash
whoami
ls -la
pwd
END
$s->write (my $f = Vq('file', Rs("zzz.sh"))); # Write code to a file
executeFileViaBash($f); # Execute the file
unlinkFile ($f); # Delete the file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $u = qx(whoami); chomp($u);
ok Assemble(emulator=>0) =~ m($u); # The Intel Software Development Emulator is way too slow on these operations.
Hash functions
Hash functions
Hash()
Hash a string addressed by rax with length held in rdi and return the hash code in r15
Example:
Mov rax, "[rbp+24]";
Cstrlen; # Length of string to hash
Mov rdi, r15;
Hash(); # Hash string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex r15;
my $e = Assemble keep=>'hash'; # Assemble to the specified file name
ok qx($e "") =~ m(r15: 0000 3F80 0000 3F80); # Test well known hashes
ok qx($e "a") =~ m(r15: 0000 3F80 C000 45B2);
if (0 and $develop) # Hash various strings # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
{my %r; my %f; my $count = 0;
my $N = RegisterSize zmm0;
if (1) # Fixed blocks
{for my $l(qw(a ab abc abcd), 'a a', 'a a')
{for my $i(1..$N)
{my $t = $l x $i;
last if $N < length $t;
my $s = substr($t.(' ' x $N), 0, $N);
next if $f{$s}++;
my $r = qx($e "$s");
say STDERR "$count $r";
if ($r =~ m(^.*r15:\s*(.*)$)m)
{push $r{$1}->@*, $s;
++$count;
}
}
}
}
if (1) # Variable blocks
{for my $l(qw(a ab abc abcd), '', 'a a', 'a a')
{for my $i(1..$N)
{my $t = $l x $i;
next if $f{$t}++;
my $r = qx($e "$t");
say STDERR "$count $r";
if ($r =~ m(^.*r15:\s*(.*)$)m)
{push $r{$1}->@*, $t;
++$count;
}
}
}
}
for my $r(keys %r)
{delete $r{$r} if $r{$r}->@* < 2;
}
say STDERR dump(\%r);
say STDERR "Keys hashed: ", $count;
confess "Duplicates : ", scalar keys(%r);
}
Unicode
Convert utf8 to utf32
GetNextUtf8CharAsUtf32(@parameters)
Get the next utf8 encoded character from the addressed memory and return it as a utf32 char
Parameter Description
1 @parameters Parameters
ConvertUtf8ToUtf32(@parameters)
Convert a string of utf8 to an allocated block of utf32 and return its address and length.
Parameter Description
1 @parameters Parameters
Example:
my @p = my ($out, $size, $fail) = (Vq(out), Vq(size), Vq('fail'));
my $opens = Vq(opens);
my $class = Vq(class);
my $Chars = Rb(0x24, 0xc2, 0xa2, 0xc9, 0x91, 0xE2, 0x82, 0xAC, 0xF0, 0x90, 0x8D, 0x88);
my $chars = Vq(chars, $Chars);
GetNextUtf8CharAsUtf32 in=>$chars, @p; # Dollar UTF-8 Encoding: 0x24 UTF-32 Encoding: 0x00000024
$out->out('out1 : '); $size->outNL(' size : ');
GetNextUtf8CharAsUtf32 in=>$chars+1, @p; # Cents UTF-8 Encoding: 0xC2 0xA2 UTF-32 Encoding: 0x000000a2
$out->out('out2 : '); $size->outNL(' size : ');
GetNextUtf8CharAsUtf32 in=>$chars+3, @p; # Alpha UTF-8 Encoding: 0xC9 0x91 UTF-32 Encoding: 0x00000251
$out->out('out3 : '); $size->outNL(' size : ');
GetNextUtf8CharAsUtf32 in=>$chars+5, @p; # Euro UTF-8 Encoding: 0xE2 0x82 0xAC UTF-32 Encoding: 0x000020AC
$out->out('out4 : '); $size->outNL(' size : ');
GetNextUtf8CharAsUtf32 in=>$chars+8, @p; # Gothic Letter Hwair UTF-8 Encoding 0xF0 0x90 0x8D 0x88 UTF-32 Encoding: 0x00010348
$out->out('out5 : '); $size->outNL(' size : ');
my $statement = qq(𝖺
𝑎𝑠𝑠𝑖𝑔𝑛 【【𝖻 𝐩𝐥𝐮𝐬 𝖼】】
AAAAAAAA); # A sample sentence to parse
my $s = Cq(statement, Rs($statement));
my $l = Cq(size, length($statement));
AllocateMemory($l, my $address = Vq(address)); # Allocate enough memory for a copy of the string
CopyMemory(source => $s, target => $address, $l);
GetNextUtf8CharAsUtf32 in=>$address, @p;
$out->out('outA : '); $size->outNL(' size : ');
GetNextUtf8CharAsUtf32 in=>$address+4, @p;
$out->out('outB : '); $size->outNL(' size : ');
GetNextUtf8CharAsUtf32 in=>$address+5, @p;
$out->out('outC : '); $size->outNL(' size : ');
GetNextUtf8CharAsUtf32 in=>$address+30, @p;
$out->out('outD : '); $size->outNL(' size : ');
GetNextUtf8CharAsUtf32 in=>$address+35, @p;
$out->out('outE : '); $size->outNL(' size : ');
$address->printOutMemoryInHexNL($l);
Cq('newLine', 0x0A)->putBIntoZmm(0, 0); # Single character classifications
Cq('newLine', 0x01)->putBIntoZmm(0, 3);
Cq('space', 0x20)->putBIntoZmm(0, 4);
Cq('space', 0x02)->putBIntoZmm(0, 7);
if (1) # Classify a utf32 string
{my $a = Dd(0x0001d5ba, 0x00000020, 0x0001d44e, 0x0000000a, 0x0001d5bb, 0x0001d429);
my $t = Cq('test', $a);
my $s = Cq('size', 6);
ClassifyCharacters4 address=>$t, size=>$s;
PrintOutStringNL "Convert some utf8 to utf32";
$s->for(sub
{my ($index, $start, $next, $end) = @_;
my $a = $t+$index * 4;
$a->setReg(r15);
KeepFree r15;
Mov r15d, "[r15]";
KeepFree r15;
PrintOutRegisterInHex r15;
});
}
if (1) # Convert utf8 test string to utf32
{my @p = my ($u32, $size32, $count) = (Vq(u32), Vq(size32), Vq(count));
ConvertUtf8ToUtf32 u8 => $s, size8 => $l, @p; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ClassifyCharacters4 address=>$u32, size=>$count;
PrintOutStringNL "Convert test statement - special characters";
$count->for(sub
{my ($index, $start, $next, $end) = @_;
my $a = $u32 + $index * 4;
$a->setReg(r15);
KeepFree r15;
Mov r15d, "[r15]";
KeepFree r15;
PrintOutRegisterInHex r15;
});
Cq('variable', 0x0) ->putDIntoZmm(0, 0); # Range classifications
Cq('variable', 0x03) ->putBIntoZmm(0, 3);
Cq('variable', 0x01D5A0)->putDIntoZmm(0, 4);
Cq('variable', 0x04) ->putBIntoZmm(0, 7);
Cq('variable', 0x01D434)->putDIntoZmm(0, 8);
Cq('variable', 0x05) ->putBIntoZmm(0, 11);
Cq('variable', 0x01D400)->putDIntoZmm(0, 12);
Cq('variable', 0x06) ->putBIntoZmm(0, 15);
Cq('variable', 0x7f) ->putDIntoZmm(1, 0);
Cq('variable', 0x03) ->putBIntoZmm(1, 3);
Cq('variable', 0x01D5D3)->putDIntoZmm(1, 4);
Cq('variable', 0x04) ->putBIntoZmm(1, 7);
Cq('variable', 0x01D467)->putDIntoZmm(1, 8);
Cq('variable', 0x05) ->putBIntoZmm(1, 11);
Cq('variable', 0x01D433)->putDIntoZmm(1, 12);
Cq('variable', 0x06) ->putBIntoZmm(1, 15);
ClassifyInRange address=>$u32, size=>$count;
PrintOutStringNL "Convert test statement - ranges";
$count->for(sub
{my ($index, $start, $next, $end) = @_;
my $a = $u32 + $index * 4;
$a->setReg(r15);
KeepFree r15;
Mov r15d, "[r15]";
KeepFree r15;
PrintOutRegisterInHex r15;
});
my $bl = Rd(0x10002045, 0x12002329, 0x1400276c, 0x16002770, 0x1c0027e6, 0x24002983, 0x26002987, 0x380029fc, 0x3a003008, 0x3e003010, 0x40003014, 0x4800ff3b, 0x4900ff3d, 0x4a00ff5b, 0x4b00ff5d, 0);
my $bh = Rd(0x11002046, 0x1300232a, 0x1500276d, 0x1b002775, 0x230027ed, 0x25002984, 0x37002998, 0x390029fd, 0x3d00300b, 0x3f003011, 0x4700301b, 0x4800ff3b, 0x4900ff3d, 0x4a00ff5b, 0x4b00ff5d, 0);
Vmovdqu8 zmm0, "[$bl]";
Vmovdqu8 zmm1, "[$bh]";
ClassifyWithInRange address=>$u32, size=>$count;
PrintOutStringNL "Convert test statement - brackets";
$count->for(sub
{my ($index, $start, $next, $end) = @_;
my $a = $u32 + $index * 4;
$a->setReg(r15);
KeepFree r15;
Mov r15d, "[r15]";
KeepFree r15;
PrintOutRegisterInHex r15;
});
MatchBrackets address=>$u32, size=>$count, $opens, $fail;
PrintOutStringNL "Convert test statement - bracket matching";
$count->for(sub
{my ($index, $start, $next, $end) = @_;
my $a = $u32 + $index * 4;
$a->setReg(r15);
KeepFree r15;
Mov r15d, "[r15]";
KeepFree r15;
PrintOutRegisterInHex r15;
});
}
$address->clearMemory($l);
$address->printOutMemoryInHexNL($l);
ok Assemble(debug => 0, eq => <<END);
out1 : 0000 0000 0000 0024 size : 0000 0000 0000 0001
out2 : 0000 0000 0000 00A2 size : 0000 0000 0000 0002
out3 : 0000 0000 0000 0251 size : 0000 0000 0000 0002
out4 : 0000 0000 0000 20AC size : 0000 0000 0000 0003
out5 : 0000 0000 0001 0348 size : 0000 0000 0000 0004
outA : 0000 0000 0001 D5BA size : 0000 0000 0000 0004
outB : 0000 0000 0000 000A size : 0000 0000 0000 0001
outC : 0000 0000 0000 0020 size : 0000 0000 0000 0001
outD : 0000 0000 0000 0020 size : 0000 0000 0000 0001
outE : 0000 0000 0000 0010 size : 0000 0000 0000 0002
F09D 96BA 0A20 F09D918E F09D 91A0 F09D91A0 F09D 9196 F09D9194 F09D 919B 20E38090 E380 90F0 9D96BB20 F09D 90A9 F09D90A5 F09D 90AE F09D90AC 20F0 9D96 BCE38091 E380 910A 4141
Convert some utf8 to utf32
r15: 0000 0000 0001 D5BA
r15: 0000 0000 0200 0020
r15: 0000 0000 0001 D44E
r15: 0000 0000 0100 000A
r15: 0000 0000 0001 D5BB
r15: 0000 0000 0001 D429
Convert test statement - special characters
r15: 0000 0000 0001 D5BA
r15: 0000 0000 0100 000A
r15: 0000 0000 0200 0020
r15: 0000 0000 0001 D44E
r15: 0000 0000 0001 D460
r15: 0000 0000 0001 D460
r15: 0000 0000 0001 D456
r15: 0000 0000 0001 D454
r15: 0000 0000 0001 D45B
r15: 0000 0000 0200 0020
r15: 0000 0000 0000 3010
r15: 0000 0000 0000 3010
r15: 0000 0000 0001 D5BB
r15: 0000 0000 0200 0020
r15: 0000 0000 0001 D429
r15: 0000 0000 0001 D425
r15: 0000 0000 0001 D42E
r15: 0000 0000 0001 D42C
r15: 0000 0000 0200 0020
r15: 0000 0000 0001 D5BC
r15: 0000 0000 0000 3011
r15: 0000 0000 0000 3011
r15: 0000 0000 0100 000A
r15: 0000 0000 0000 0041
r15: 0000 0000 0000 0041
r15: 0000 0000 0000 0041
r15: 0000 0000 0000 0041
r15: 0000 0000 0000 0041
r15: 0000 0000 0000 0041
r15: 0000 0000 0000 0041
r15: 0000 0000 0000 0041
Convert test statement - ranges
r15: 0000 0000 0401 D5BA
r15: 0000 0000 0100 000A
r15: 0000 0000 0200 0020
r15: 0000 0000 0501 D44E
r15: 0000 0000 0501 D460
r15: 0000 0000 0501 D460
r15: 0000 0000 0501 D456
r15: 0000 0000 0501 D454
r15: 0000 0000 0501 D45B
r15: 0000 0000 0200 0020
r15: 0000 0000 0000 3010
r15: 0000 0000 0000 3010
r15: 0000 0000 0401 D5BB
r15: 0000 0000 0200 0020
r15: 0000 0000 0601 D429
r15: 0000 0000 0601 D425
r15: 0000 0000 0601 D42E
r15: 0000 0000 0601 D42C
r15: 0000 0000 0200 0020
r15: 0000 0000 0401 D5BC
r15: 0000 0000 0000 3011
r15: 0000 0000 0000 3011
r15: 0000 0000 0100 000A
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
Convert test statement - brackets
r15: 0000 0000 0401 D5BA
r15: 0000 0000 0100 000A
r15: 0000 0000 0200 0020
r15: 0000 0000 0501 D44E
r15: 0000 0000 0501 D460
r15: 0000 0000 0501 D460
r15: 0000 0000 0501 D456
r15: 0000 0000 0501 D454
r15: 0000 0000 0501 D45B
r15: 0000 0000 0200 0020
r15: 0000 0000 3E00 3010
r15: 0000 0000 3E00 3010
r15: 0000 0000 0401 D5BB
r15: 0000 0000 0200 0020
r15: 0000 0000 0601 D429
r15: 0000 0000 0601 D425
r15: 0000 0000 0601 D42E
r15: 0000 0000 0601 D42C
r15: 0000 0000 0200 0020
r15: 0000 0000 0401 D5BC
r15: 0000 0000 3F00 3011
r15: 0000 0000 3F00 3011
r15: 0000 0000 0100 000A
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
Convert test statement - bracket matching
r15: 0000 0000 0401 D5BA
r15: 0000 0000 0100 000A
r15: 0000 0000 0200 0020
r15: 0000 0000 0501 D44E
r15: 0000 0000 0501 D460
r15: 0000 0000 0501 D460
r15: 0000 0000 0501 D456
r15: 0000 0000 0501 D454
r15: 0000 0000 0501 D45B
r15: 0000 0000 0200 0020
r15: 0000 0000 3E00 0015
r15: 0000 0000 3E00 0014
r15: 0000 0000 0401 D5BB
r15: 0000 0000 0200 0020
r15: 0000 0000 0601 D429
r15: 0000 0000 0601 D425
r15: 0000 0000 0601 D42E
r15: 0000 0000 0601 D42C
r15: 0000 0000 0200 0020
r15: 0000 0000 0401 D5BC
r15: 0000 0000 3F00 000B
r15: 0000 0000 3F00 000A
r15: 0000 0000 0100 000A
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
r15: 0000 0000 0300 0041
0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
END
ClassifyCharacters4(@parameters)
Classify the utf32 characters in a block of memory of specified length using zmm0 formatted in double words with each word having the classification in the highest 8 bits and the utf32 character in the lower 21 bits. The classification bits are copied into each utf32 character in the block of memory.
Parameter Description
1 @parameters Parameters
ClassifyInRange(@parameters)
Classify the utf32 characters in a block of memory of specified length using zmm0, zmm1 formatted in double words with each word in zmm1 having the classification in the highest 8 bits and with zmm0 and zmm1 having the utf32 character at the start (zmm0) and end (zmm1) of each range in the lower 21 bits. The classification bits from the first matching range are copied into each utf32 character in the block of memory.
Parameter Description
1 @parameters Parameters
ClassifyWithInRange(@parameters)
Classify the utf32 characters in a block of memory of specified length using zmm0, zmm1 formatted in double words with the classification range in the highest 8 bits of zmm0 and zmm1 and the utf32 character at the start (zmm0) and end (zmm1) of each range in the lower 21 bits. The classification bits from the position within the first matching range are copied into each utf32 character in the block of memory.
Parameter Description
1 @parameters Parameters
MatchBrackets(@parameters)
Replace a utf32 character with 24 bits of offset to the matching opening or closing bracket. Opening brackets have even codes from 0x10 to 0x4e while the corresponding closing bracket has a code one higher.
Parameter Description
1 @parameters Parameters
Short Strings
Operations on Short Strings
LoadShortStringFromMemoryToZmm2($zmm)
Load the short string addressed by rax into the zmm register with the specified number
Parameter Description
1 $zmm Zmm register to load
LoadShortStringFromMemoryToZmm($zmm, $address)
Load the short string addressed by rax into the zmm register with the specified number
Parameter Description
1 $zmm Zmm register to load
2 $address Address of string in memory
Example:
my $s = Rb(3, 0x01, 0x02, 0x03);
my $t = Rb(7, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a);
LoadShortStringFromMemoryToZmm 0, $s; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
LoadShortStringFromMemoryToZmm 1, $t; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ConcatenateShortStrings(0, 1);
PrintOutRegisterInHex xmm0;
PrintOutRegisterInHex xmm1;
my $r = Assemble;
ok $r =~ m(xmm0: 0000 0000 000A 0908 0706 0504 0302 010A);
ok $r =~ m(xmm1: 0000 0000 0000 0000 0A09 0807 0605 0407);
GetLengthOfShortString($reg, $zmm)
Get the length of the short string held in the numbered zmm register into the specified register
Parameter Description
1 $reg Register to hold length
2 $zmm Number of zmm register containing string
SetLengthOfShortString($zmm, $reg)
Set the length of the short string held in the numbered zmm register into the specified register
Parameter Description
1 $zmm Number of zmm register containing string
2 $reg Register to hold length
ConcatenateShortStrings($left, $right)
Concatenate the numbered source zmm containing a short string with the short string in the numbered target zmm.
Parameter Description
1 $left Target zmm
2 $right Source zmm
Byte Strings
Operations on Byte Strings
Cstrlen()
Length of the C style string addressed by rax returning the length in r15
Example:
my $s = Rs("abcd");
Mov rax, $s;
Cstrlen; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex r15;
ok Assemble =~ m(r15: 0000 0000 0000 0004);
CreateByteString(%options)
Create an relocatable string of bytes in an arena and returns its address in rax. Optionally add a chain header so that 64 byte blocks of memory can be freed and reused within the byte string.
Parameter Description
1 %options Free=>1 adds a free chain.
Example:
my $a = CreateByteString; # Create a string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$a->q('aa');
$a->out;
PrintOutNL;
is_deeply Assemble, <<END; # Assemble and execute
aa
END
my $a = CreateByteString; # Create a string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $b = CreateByteString; # Create a string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$a->q('aa');
$b->q('bb');
$a->out;
PrintOutNL;
$b->out;
PrintOutNL;
is_deeply Assemble, <<END; # Assemble and execute
aa
bb
END
my $a = CreateByteString; # Create a string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $b = CreateByteString; # Create a string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$a->q('aa');
$a->q('AA');
$a->out;
PrintOutNL;
is_deeply Assemble, <<END; # Assemble and execute
aaAA
END
my $a = CreateByteString; # Create a string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $b = CreateByteString; # Create a string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$a->q('aa');
$b->q('bb');
$a->q('AA');
$b->q('BB');
$a->q('aa');
$b->q('bb');
$a->out;
$b->out;
PrintOutNL;
is_deeply Assemble, <<END; # Assemble and execute
aaAAaabbBBbb
END
my $a = CreateByteString; # Create a string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$a->q('ab');
my $b = CreateByteString; # Create target byte string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$b->append(source=>$a->bs);
$b->append(source=>$a->bs);
$a->append(source=>$b->bs);
$b->append(source=>$a->bs);
$a->append(source=>$b->bs);
$b->append(source=>$a->bs);
$b->append(source=>$a->bs);
$b->append(source=>$a->bs);
$b->append(source=>$a->bs);
$a->out; PrintOutNL; # Print byte string
$b->out; PrintOutNL; # Print byte string
$a->length(my $sa = Vq(size)); $sa->outNL;
$b->length(my $sb = Vq(size)); $sb->outNL;
$a->clear;
$a->length(my $sA = Vq(size)); $sA->outNL;
$b->length(my $sB = Vq(size)); $sB->outNL;
is_deeply Assemble, <<END; # Assemble and execute
abababababababab
ababababababababababababababababababababababababababababababababababababab
size: 0000 0000 0000 0010
size: 0000 0000 0000 004A
size: 0000 0000 0000 0000
size: 0000 0000 0000 004A
END
Nasm::X86::ByteString::chain($byteString, $bs, $variable, @offsets)
Return a variable with the end point of a chain of double words in the byte string starting at the specified variable.
Parameter Description
1 $byteString Byte string descriptor
2 $bs Byte string locator
3 $variable Start variable
4 @offsets Offsets chain
Example:
my $format = Rd(map{4*$_+24} 0..64);
my $b = CreateByteString;
my $a = $b->allocBlock;
Vmovdqu8 zmm31, "[$format]";
$b->putBlock($b->bs, $a, 31);
my $r = $b->chain($b->bs, Vq(start, 0x18), 4); $r->outNL("chain1: ");
my $s = $b->chain($b->bs, $r, 4); $s->outNL("chain2: ");
my $t = $b->chain($b->bs, $s, 4); $t->outNL("chain3: ");
my $A = $b->chain($b->bs, Vq(start, 0x18), 4, 4, 4); $A->outNL("chain4: "); # Get a long chain
$b->putChain($b->bs, Vq(start, 0x18), Vq(end, 0xff), 4, 4, 4); # Put at the end of a long chain
$b->dump;
my $sub = Subroutine
{my ($p) = @_; # Parameters
If ($$p{c} == -1,
sub {PrintOutStringNL "C is minus one"},
sub {PrintOutStringNL "C is NOT minus one"},
);
If ($$p{d} == -1,
sub {PrintOutStringNL "D is minus one"},
sub {PrintOutStringNL "D is NOT minus one"},
);
my $C = $$p{c}->clone;
$C->outNL;
$$p{e} += 1;
$$p{e}->outNL('E: ');
$$p{f}->outNL('F1: ');
$$p{f}++;
$$p{f}->outNL('F2: ');
} name=> 'aaa', in => {c => 3}, io => {d => 3, e => 3, f => 3};
my $c = Cq(c, -1);
my $d = Cq(d, -1);
my $e = Vq(e, 1);
my $f = Vq(f, 2);
$sub->call($c, $d, $e, $f);
$f->outNL('F3: ');
ok Assemble(debug => 0, eq => <<END);
chain1: 0000 0000 0000 001C
chain2: 0000 0000 0000 0020
chain3: 0000 0000 0000 0024
chain4: 0000 0000 0000 0024
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0058
0000: 0010 0000 0000 00005800 0000 0000 00000000 0000 0000 00001800 0000 1C00 00002000 0000 FF00 00002800 0000 2C00 00003000 0000 3400 00003800 0000 3C00 0000
0040: 4000 0000 4400 00004800 0000 4C00 00005000 0000 5400 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
C is minus one
D is minus one
Clone of c: FFFF FFFF FFFF FFFF
E: 0000 0000 0000 0002
F1: 0000 0000 0000 0002
F2: 0000 0000 0000 0003
F3: 0000 0000 0000 0003
END
Nasm::X86::ByteString::putChain($byteString, $bs, $start, $value, @offsets)
Write the double word in the specified variable to the double word location at the the specified offset in the specified byte string.
Parameter Description
1 $byteString Byte string descriptor
2 $bs Byte string locator variable
3 $start Start variable
4 $value Value to put as a variable
5 @offsets Offsets chain
Nasm::X86::ByteString::length($byteString, @variables)
Get the length of a byte string
Parameter Description
1 $byteString Byte string descriptor
2 @variables Variables
Nasm::X86::ByteString::makeReadOnly($byteString)
Make a byte string read only
Parameter Description
1 $byteString Byte string descriptor
Nasm::X86::ByteString::makeWriteable($byteString)
Make a byte string writable
Parameter Description
1 $byteString Byte string descriptor
Nasm::X86::ByteString::allocate($byteString, @variables)
Allocate the amount of space indicated in rdi in the byte string addressed by rax and return the offset of the allocation in the arena in rdi
Parameter Description
1 $byteString Byte string descriptor
2 @variables Variables
Nasm::X86::ByteString::blockSize($byteString)
Size of a block
Parameter Description
1 $byteString Byte string
Nasm::X86::ByteString::allocZmmBlock($byteString, @variables)
Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
Parameter Description
1 $byteString Byte string
2 @variables Variables
Nasm::X86::ByteString::allocBlock($byteString)
Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
Parameter Description
1 $byteString Byte string
Example:
my $a = CreateByteString; $a->dump;
my $b1 = $a->allocBlock; $a->dump;
my $b2 = $a->allocBlock; $a->dump;
$a->freeBlock($b2); $a->dump;
$a->freeBlock($b1); $a->dump;
ok Assemble(debug => 0, eq => <<END);
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0018
0000: 0010 0000 0000 00001800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0058
0000: 0010 0000 0000 00005800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0098
0000: 0010 0000 0000 00009800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0098
0000: 0010 0000 0000 00009800 0000 0000 00005800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0098
0000: 0010 0000 0000 00009800 0000 0000 00001800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 5800 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
END
Nasm::X86::ByteString::freeBlock($byteString, @variables)
Free a block in a byte string by placing it on the free chain
Parameter Description
1 $byteString Byte string descriptor
2 @variables Variables
Example:
my $a = CreateByteString; $a->dump;
my $b1 = $a->allocBlock; $a->dump;
my $b2 = $a->allocBlock; $a->dump;
$a->freeBlock($b2); $a->dump;
$a->freeBlock($b1); $a->dump;
ok Assemble(debug => 0, eq => <<END);
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0018
0000: 0010 0000 0000 00001800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0058
0000: 0010 0000 0000 00005800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0098
0000: 0010 0000 0000 00009800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0098
0000: 0010 0000 0000 00009800 0000 0000 00005800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 0098
0000: 0010 0000 0000 00009800 0000 0000 00001800 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0040: 0000 0000 0000 00000000 0000 0000 00000000 0000 5800 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
0080: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
00C0: 0000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 00000000 0000 0000 0000
END
Nasm::X86::ByteString::getBlock($byteString, $bsa, $block, $zmm)
Get the block with the specified offset in the specified block string and return it in the numbered zmm
Parameter Description
1 $byteString Byte string descriptor
2 $bsa Byte string variable
3 $block Offset of the block as a variable
4 $zmm Number of zmm register to contain block
Nasm::X86::ByteString::putBlock($byteString, $bsa, $block, $zmm)
Write the numbered zmm to the block at the specified offset in the specified byte string
Parameter Description
1 $byteString Byte string descriptor
2 $bsa Byte string variable
3 $block Block in byte string
4 $zmm Content variable
Nasm::X86::ByteString::m($byteString, @variables)
Append the content with length rdi addressed by rsi to the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
2 @variables Variables
Nasm::X86::ByteString::q($byteString, $string)
Append a constant string to the byte string
Parameter Description
1 $byteString Byte string descriptor
2 $string String
Nasm::X86::ByteString::ql($byteString, $const)
Append a quoted string containing new line characters to the byte string addressed by rax
Parameter Description
1 $byteString Byte string
2 $const Constant
Nasm::X86::ByteString::char($byteString, $char)
Append a character expressed as a decimal number to the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
2 $char Number of character to be appended
Nasm::X86::ByteString::nl($byteString)
Append a new line to the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
Nasm::X86::ByteString::z($byteString)
Append a trailing zero to the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
Nasm::X86::ByteString::append($byteString, @variables)
Append one byte string to another
Parameter Description
1 $byteString Byte string descriptor
2 @variables Variables
Nasm::X86::ByteString::clear($byteString)
Clear the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
Nasm::X86::ByteString::write($byteString, @variables)
Write the content in a byte string addressed by rax to a temporary file and replace the byte string content with the name of the temporary file
Parameter Description
1 $byteString Byte string descriptor
2 @variables Variables
Nasm::X86::ByteString::read($byteString, @variables)
Read the named file (terminated with a zero byte) and place it into the named byte string.
Parameter Description
1 $byteString Byte string descriptor
2 @variables Variables
Nasm::X86::ByteString::out($byteString)
Print the specified byte string addressed by rax on sysout
Parameter Description
1 $byteString Byte string descriptor
Nasm::X86::ByteString::dump($byteString, $depth)
Dump details of a byte string
Parameter Description
1 $byteString Byte string descriptor
2 $depth Optional amount of memory to dump
Block Strings
Strings made from zmm sized blocks of text
Nasm::X86::ByteString::CreateBlockString($byteString)
Create a string from a doubly link linked list of 64 byte blocks linked via 4 byte offsets in the byte string addressed by rax and return its descriptor
Parameter Description
1 $byteString Byte string description
Nasm::X86::BlockString::address($blockString)
Address of a block string
Parameter Description
1 $blockString Block string descriptor
Nasm::X86::BlockString::allocBlock($blockString)
Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
Parameter Description
1 $blockString Block string descriptor
Nasm::X86::BlockString::getBlockLength($blockString, $zmm)
Get the block length of the numbered zmm and return it in a variable
Parameter Description
1 $blockString Block string descriptor
2 $zmm Number of zmm register
Nasm::X86::BlockString::setBlockLengthInZmm($blockString, $length, $zmm)
Set the block length of the numbered zmm to the specified length
Parameter Description
1 $blockString Block string descriptor
2 $length Length as a variable
3 $zmm Number of zmm register
Nasm::X86::BlockString::getBlock($blockString, $bsa, $block, $zmm)
Get the block with the specified offset in the specified block string and return it in the numbered zmm
Parameter Description
1 $blockString Block string descriptor
2 $bsa Byte string variable
3 $block Offset of the block as a variable
4 $zmm Number of zmm register to contain block
Nasm::X86::BlockString::putBlock($blockString, $bsa, $block, $zmm)
Write the numbered zmm to the block at the specified offset in the specified byte string
Parameter Description
1 $blockString Block string descriptor
2 $bsa Byte string variable
3 $block Block in byte string
4 $zmm Content variable
Nasm::X86::BlockString::getNextAndPrevBlockOffsetFromZmm($blockString, $zmm)
Get the offsets of the next and previous blocks as variables from the specified zmm
Parameter Description
1 $blockString Block string descriptor
2 $zmm Zmm containing block
Nasm::X86::BlockString::putNextandPrevBlockOffsetIntoZmm($blockString, $zmm, $next, $prev)
Save next and prev offsets into a zmm representing a block
Parameter Description
1 $blockString Block string descriptor
2 $zmm Zmm containing block
3 $next Next offset as a variable
4 $prev Prev offset as a variable
Nasm::X86::BlockString::dump($blockString)
Dump a block string to sysout
Parameter Description
1 $blockString Block string descriptor
Nasm::X86::BlockString::len($blockString, $size)
Find the length of a block string
Parameter Description
1 $blockString Block string descriptor
2 $size Size variable
Nasm::X86::BlockString::concatenate($target, $source)
Concatenate two block strings by appending a copy of the source to the target block string.
Parameter Description
1 $target Target block string
2 $source Source block string
Nasm::X86::BlockString::insertChar($blockString, @variables)
Insert a character into a block string
Parameter Description
1 $blockString Block string
2 @variables Variables
Nasm::X86::BlockString::deleteChar($blockString, @variables)
Delete a character in a block string
Parameter Description
1 $blockString Block string
2 @variables Variables
Nasm::X86::BlockString::getCharacter($blockString, @variables)
Get a character from a block string
Parameter Description
1 $blockString Block string
2 @variables Variables
Nasm::X86::BlockString::append($blockString, @variables)
Append the specified content in memory to the specified block string
Parameter Description
1 $blockString Block string descriptor
2 @variables Variables
Nasm::X86::BlockString::clear($blockString)
Clear the block by freeing all but the first block
Parameter Description
1 $blockString Block string descriptor
Block Array
Array constructed as a tree of blocks in a byte string
Nasm::X86::ByteString::CreateBlockArray($byteString)
Create a block array in a byte string
Parameter Description
1 $byteString Byte string description
Nasm::X86::BlockArray::address($blockArray)
Address of a block string
Parameter Description
1 $blockArray Block array descriptor
Nasm::X86::BlockArray::allocBlock($blockArray)
Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
Parameter Description
1 $blockArray Block array descriptor
Nasm::X86::BlockArray::dump($blockArray, @variables)
Dump a block array
Parameter Description
1 $blockArray Block array descriptor
2 @variables Variables
Nasm::X86::BlockArray::push($blockArray, @variables)
Push an element onto the array
Parameter Description
1 $blockArray Block array descriptor
2 @variables Variables
Nasm::X86::BlockArray::pop($blockArray, @variables)
Pop an element from an array
Parameter Description
1 $blockArray Block array descriptor
2 @variables Variables
Nasm::X86::BlockArray::get($blockArray, @variables)
Get an element from the array
Parameter Description
1 $blockArray Block array descriptor
2 @variables Variables
Nasm::X86::BlockArray::put($blockArray, @variables)
Put an element into an array as long as it is with in its limits established by pushing.
Parameter Description
1 $blockArray Block array descriptor
2 @variables Variables
Block Multi Way Tree
Multi Way Tree constructed as a tree of blocks in a byte string
Nasm::X86::ByteString::CreateBlockMultiWayTree($byteString)
Create a block multi way tree in a byte string
Parameter Description
1 $byteString Byte string description
Example:
Mov r14, 0;
Kmovq k0, r14;
KeepFree r14;
Ktestq k0, k0;
IfZ {PrintOutStringNL "0 & 0 == 0"};
PrintOutZF;
LoadConstantIntoMaskRegister k1, 1;
Ktestq k1, k1;
IfNz {PrintOutStringNL "1 & 1 != 0"};
PrintOutZF;
LoadConstantIntoMaskRegister k2, eval "0b".(('1'x4).('0'x4))x2;
PrintOutRegisterInHex k0, k1, k2;
Mov r15, 0x89abcdef;
Mov r14, 0x01234567;
Shl r14, 32;
Or r15, r14;
Push r15;
Push r15;
KeepFree r15;
PopEax; PrintRaxInHex($stdout, 3); PrintOutNL; KeepFree rax;
my $a = Vq('aaaa');
$a->pop;
$a->push;
$a->outNL;
PopEax; PrintRaxInHex($stdout, 3); PrintOutNL; KeepFree rax;
ok Assemble(debug => 0, eq => <<END);
0 & 0 == 0
ZF=1
1 & 1 != 0
ZF=0
k0: 0000 0000 0000 0000
k1: 0000 0000 0000 0001
k2: 0000 0000 0000 F0F0
89AB CDEF
aaaa: 89AB CDEF 0123 4567
0123 4567
END
Nasm::X86::BlockMultiWayTree::find($bmt, @variables)
Find a key in a tree and return its associated data
Parameter Description
1 $bmt Block multi way tree descriptor
2 @variables Variables
Nasm::X86::BlockMultiWayTree::insert($bmt, @variables)
Insert a (key, data) pair into the tree
Parameter Description
1 $bmt Block multi way tree descriptor
2 @variables Variables
Nasm::X86::BlockMultiWayTree::getKeysData($bmt, $offset, $zmmKeys, $zmmData)
Load the keys and data blocks for a node
Parameter Description
1 $bmt Block multi way tree descriptor
2 $offset Offset as a variable
3 $zmmKeys Numbered zmm for keys
4 $zmmData Numbered data for keys
Nasm::X86::BlockMultiWayTree::putKeysData($bmt, $offset, $zmmKeys, $zmmData)
Save the key and data blocks for a node
Parameter Description
1 $bmt Block multi way tree descriptor
2 $offset Offset as a variable
3 $zmmKeys Numbered zmm for keys
4 $zmmData Numbered data for keys
Nasm::X86::BlockMultiWayTree::getNode($bmt, $offset, $zmmNode)
Load the child nodes for a node
Parameter Description
1 $bmt Block multi way tree descriptor
2 $offset Offset of nodes
3 $zmmNode Numbered zmm for keys
Nasm::X86::BlockMultiWayTree::getKeysDataNode($bmt, $offset, $zmmKeys, $zmmData, $zmmNode)
Load the keys, data and child nodes for a node
Parameter Description
1 $bmt Block multi way tree descriptor
2 $offset Offset as a variable
3 $zmmKeys Numbered zmm for keys
4 $zmmData Numbered data for keys
5 $zmmNode Numbered numbered for keys
Nasm::X86::BlockMultiWayTree::putKeysDataNode($bmt, $offset, $zmmKeys, $zmmData, $zmmNode)
Save the keys, data and child nodes for a node
Parameter Description
1 $bmt Block multi way tree descriptor
2 $offset Offset as a variable
3 $zmmKeys Numbered zmm for keys
4 $zmmData Numbered data for keys
5 $zmmNode Numbered numbered for keys
Nasm::X86::BlockMultiWayTree::getLengthInKeys($bmt, $zmm)
Get the length of the keys block in the numbered zmm and return it as a variable
Parameter Description
1 $bmt Block multi way tree descriptor
2 $zmm Zmm number
Nasm::X86::BlockMultiWayTree::putLengthInKeys($bmt, $zmm, $length)
Get the length of the block in the numbered zmm from the specified variable
Parameter Description
1 $bmt Block multi way tree
2 $zmm Zmm number
3 $length Length variable
Nasm::X86::BlockMultiWayTree::getUpFromData($bmt, $zmm)
Get the up offset from the data block in the numbered zmm and return it as a variable
Parameter Description
1 $bmt Block multi way tree descriptor
2 $zmm Zmm number
Nasm::X86::BlockMultiWayTree::putUpIntoData($bmt, $offset, $zmm)
Put the offset of the parent keys block expressed as a variable into the numbered zmm
Parameter Description
1 $bmt Block multi way tree descriptor
2 $offset Variable containing up offset
3 $zmm Zmm number
Nasm::X86::BlockMultiWayTree::getLoop($bmt, $zmm)
Return the value of the loop field as a variable
Parameter Description
1 $bmt Block multi way tree descriptor
2 $zmm Numbered zmm
Nasm::X86::BlockMultiWayTree::putLoop($bmt, $value, $zmm)
Set the value of the loop field from a variable
Parameter Description
1 $bmt Block multi way tree descriptor
2 $value Variable containing offset of next loop entry
3 $zmm Numbered zmm
Nasm::X86::BlockMultiWayTree::leftOrRightMost($bmt, $dir, @variables)
Return the left most or right most node
Parameter Description
1 $bmt Block multi way tree descriptor
2 $dir Direction: left = 0 or right = 1
3 @variables Variables
Nasm::X86::BlockMultiWayTree::leftMost($bmt, @variables)
Return the left most node
Parameter Description
1 $bmt Block multi way tree descriptor
2 @variables Variables
Nasm::X86::BlockMultiWayTree::rightMost($bmt, @variables)
Return the right most node
Parameter Description
1 $bmt Block multi way tree descriptor
2 @variables Variables
Nasm::X86::BlockMultiWayTree::nodeFromData($bmt, $data, $node)
Load the the node block into the numbered zmm corresponding to the data block held in the numbered zmm.
Parameter Description
1 $bmt Block multi way tree descriptor
2 $data Numbered zmm containing data
3 $node Numbered zmm to hold node block
Nasm::X86::BlockMultiWayTree::address($bmt)
Address of the byte string containing a block multi way tree
Parameter Description
1 $bmt Block multi way tree descriptor
Nasm::X86::BlockMultiWayTree::allocBlock($bmt, @variables)
Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
Parameter Description
1 $bmt Block multi way tree descriptor
2 @variables Variables
Nasm::X86::BlockMultiWayTree::depth($bmt, @variables)
Return the depth of a node within a tree.
Parameter Description
1 $bmt Block multi way tree descriptor
2 @variables Variables
Nasm::X86::BlockMultiWayTree::iterator($b)
Iterate through a multi way tree
Parameter Description
1 $b Block multi way tree
Nasm::X86::BlockMultiWayTree::Iterator::next($iter)
Next element in the tree
Parameter Description
1 $iter Iterator
Nasm::X86::BlockMultiWayTree::by($b, $body)
Call the specified body with each (key, data) from the specified tree in order
Parameter Description
1 $b Block Multi Way Tree descriptor
2 $body Body
Assemble
Assemble generated code
CallC($sub, @parameters)
Call a C subroutine
Parameter Description
1 $sub Name of the sub to call
2 @parameters Parameters
Example:
my $format = Rs "Hello %s
";
my $data = Rs "World";
Extern qw(printf exit malloc strcpy); Link 'c';
CallC 'malloc', length($format)+1; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov r15, rax;
CallC 'strcpy', r15, $format; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
CallC 'printf', r15, $data; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
CallC 'exit', 0; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble(eq => <<END);
Hello World
END
Extern(@externalReferences)
Name external references
Parameter Description
1 @externalReferences External references
Example:
my $format = Rs "Hello %s
";
my $data = Rs "World";
Extern qw(printf exit malloc strcpy); Link 'c'; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
CallC 'malloc', length($format)+1;
Mov r15, rax;
CallC 'strcpy', r15, $format;
CallC 'printf', r15, $data;
CallC 'exit', 0;
ok Assemble(eq => <<END);
Hello World
END
Link(@libraries)
Libraries to link with
Parameter Description
1 @libraries External references
Example:
my $format = Rs "Hello %s
";
my $data = Rs "World";
Extern qw(printf exit malloc strcpy); Link 'c'; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
CallC 'malloc', length($format)+1;
Mov r15, rax;
CallC 'strcpy', r15, $format;
CallC 'printf', r15, $data;
CallC 'exit', 0;
ok Assemble(eq => <<END);
Hello World
END
Start()
Initialize the assembler
Exit($c)
Exit with the specified return code or zero if no return code supplied. Assemble() automatically adds a call to Exit(0) if the last operation in the program is not a call to Exit.
Parameter Description
1 $c Return code
Assemble(%options)
Assemble the generated code
Parameter Description
1 %options Options
Example:
PrintOutStringNL "Hello World";
PrintOutStringNL "Hello
World";
PrintErrStringNL "Hello World";
ok Assemble(debug => 0, eq => <<END); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Hello World
Hello
World
END
Hash Definitions
Nasm::X86 Definition
Iterator
Output fields
bs
Byte string definition
constant
Constant if true
count
Counter - number of node
data
Data at this position
depth
Lexical depth of scope
expr
Expression that initializes the variable
first
Variable addressing offset to first block of keys
free
Free chain offset
head
Offset of header block
key
Key at this position
keys
Offset of keys in header
label
Address in memory
laneSize
Size of the lanes in this variable
length
Offset of length in keys block
links
Location of links in bytes in zmm
loop
Offset of keys, data, node loop
maxKeys
Maximum number of keys
maxNodes
Maximum number of children per parent.
minKeys
Minimum number of keys
more
Iteration not yet finished
name
Name of the variable
next
Location of next offset in block in bytes
node
Current node within tree
number
Number of this scope
parent
Parent scope
pos
Current position within node
prev
Location of prev offset in block in bytes
purpose
Purpose of this variable
reference
Reference to another variable
saturate
Computations should saturate rather then wrap if true
signed
Elements of x|y|zmm registers are signed if true
size
Size field details
slots1
Number of slots in first block
slots2
Number of slots in second and subsequent blocks
structure
Structure details
tree
Tree we are iterating over
up
Offset of up in data block
used
Used field details
width
Width of a key or data slot
Attributes
The following is a list of all the attributes in this package. A method coded with the same name in your package will over ride the method of the same name in this package and thus provide your value for the attribute in place of the default value supplied for this attribute by this package.
Replaceable Attribute List
Pi32 Pi64
Pi32
Pi as a 32 bit float
Pi64
Pi as a 64 bit float
Private Methods
Label()
Create a unique label
Dbwdq($s, @d)
Layout data
Parameter Description
1 $s Element size
2 @d Data to be laid out
Rbwdq($s, @d)
Layout data
Parameter Description
1 $s Element size
2 @d Data to be laid out
hexTranslateTable()
Create/address a hex translate table and return its label
PrintOutRipInHex()
Print the instruction pointer in hex
PrintOutRflagsInHex()
Print the flags register in hex
PushRR(@r)
Push registers onto the stack without tracking
Parameter Description
1 @r Register
PushR(@r)
Push registers onto the stack
Parameter Description
1 @r Register
Example:
Mov rax, 0x11111111;
Mov rbx, 0x22222222;
PushR my @save = (rax, rbx); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rax, 0x33333333;
PopR @save;
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
is_deeply Assemble,<<END;
rax: 0000 0000 1111 1111
rbx: 0000 0000 2222 2222
END
PopRR(@r)
Pop registers from the stack without tracking
Parameter Description
1 @r Register
ClassifyRange($recordOffsetInRange, @parameters)
Implementation of ClassifyInRange and ClassifyWithinRange
Parameter Description
1 $recordOffsetInRange Record offset in range if true
2 @parameters Parameters
Nasm::X86::ByteString::updateSpace($byteString, @variables)
Make sure that the byte string addressed by rax has enough space to accommodate content of length rdi
Parameter Description
1 $byteString Byte string descriptor
2 @variables Variables
Nasm::X86::ByteString::firstFreeBlock($byteString)
Create and load a variable with the first free block on the free block chain or zero if no such block in the given byte string
Parameter Description
1 $byteString Byte string address as a variable
Nasm::X86::ByteString::setFirstFreeBlock($byteString, $offset)
Set the first free block field from a variable
Parameter Description
1 $byteString Byte string descriptor
2 $offset First free block offset as a variable
Nasm::X86::BlockMultiWayTree::allocKeysDataNode($bmt, $K, $D, $N, @variables)
Allocate a keys/data/node block and place it in the numbered zmm registers
Parameter Description
1 $bmt Block multi way tree descriptor
2 $K Numbered zmm for keys
3 $D Numbered zmm for data
4 $N Numbered zmm for children
5 @variables Variables
Nasm::X86::BlockMultiWayTree::splitNode($bmt, $bs, $node, $key, @variables)
Split a node given its offset in a byte string retaining the key being inserted in the node split while putting the remainder to the left or right.
Parameter Description
1 $bmt Block multi way tree descriptor
2 $bs Backing byte string
3 $node Offset of node
4 $key Key
5 @variables Variables
Nasm::X86::BlockMultiWayTree::reParent($bmt, $bs, $PK, $PD, $PN, @variables)
Reparent the children of a node held in registers. The children are in the backing byte string not registers.
Parameter Description
1 $bmt Block multi way tree descriptor
2 $bs Backing byte string
3 $PK Numbered zmm key node
4 $PD Numbered zmm data node
5 $PN Numbered zmm child node
6 @variables Variables
Nasm::X86::BlockMultiWayTree::splitFullRoot($bmt, $bs)
Split a full root block held in 31..29 and place the left block in 28..26 and the right block in 25..23. The left and right blocks should have their loop offsets set so they can be inserted into the root.
Parameter Description
1 $bmt Block multi way tree descriptor
2 $bs Byte string locator
Nasm::X86::BlockMultiWayTree::splitFullLeftNode($bmt, $bs)
Split a full left node block held in 28..26 whose parent is in 31..29 and place the new right block in 25..23. The parent is assumed to be not full. The loop and length fields are assumed to be authoritative and hence are preserved.
Parameter Description
1 $bmt Block multi way tree descriptor
2 $bs Byte string locator
Example:
my $Sk = Rd(17..28, 0, 0, 12, 0xFF);
my $Sd = Rd(17..28, 0, 0, 0xDD, 0xEE);
my $Sn = Rd(1..13, 0, 0, 0xCC);
my $sk = Rd(1..14, 14, 0xA1);
my $sd = Rd(1..14, 0xCC, 0xA2);
my $sn = Rd(1..15, 0xA3);
my $rk = Rd((0)x14, 14, 0xB1);
my $rd = Rd((0)x14, 0xCC, 0xB2);
my $rn = Rd((0)x15, 0xB3);
my $b = CreateByteString;
my $t = $b->CreateBlockMultiWayTree;
Vmovdqu8 zmm31, "[$Sk]";
Vmovdqu8 zmm30, "[$Sd]";
Vmovdqu8 zmm29, "[$Sn]";
Vmovdqu8 zmm28, "[$sk]";
Vmovdqu8 zmm27, "[$sd]";
Vmovdqu8 zmm26, "[$sn]";
Vmovdqu8 zmm25, "[$rk]";
Vmovdqu8 zmm24, "[$rd]";
Vmovdqu8 zmm23, "[$rn]";
$t->splitFullLeftNode($b->bs);
PrintOutRegisterInHex reverse zmm(23..31);
ok Assemble(debug => 0, eq => <<END);
zmm31: 0000 00FF 0000 000D 0000 0000 0000 0000 0000 001C 0000 001B 0000 001A 0000 0019 0000 0018 0000 0017 0000 0016 0000 0015 0000 0014 0000 0013 0000 0012 0000 0011
zmm30: 0000 00EE 0000 00DD 0000 0000 0000 0000 0000 001C 0000 001B 0000 001A 0000 0019 0000 0018 0000 0017 0000 0016 0000 0015 0000 0014 0000 0013 0000 0012 0000 0011
zmm29: 0000 00CC 0000 0000 0000 0000 0000 000D 0000 000C 0000 000B 0000 000A 0000 0009 0000 0008 0000 0007 0000 0006 0000 0005 0000 0004 0000 0003 0000 0002 0000 0001
zmm28: 0000 00A1 0000 0007 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0007 0000 0006 0000 0005 0000 0004 0000 0003 0000 0002 0000 0001
zmm27: 0000 00A2 0000 00CC 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0007 0000 0006 0000 0005 0000 0004 0000 0003 0000 0002 0000 0001
zmm26: 0000 00A3 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0007 0000 0006 0000 0005 0000 0004 0000 0003 0000 0002 0000 0001
zmm25: 0000 00B1 0000 0006 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 000E 0000 000D 0000 000C 0000 000B 0000 000A 0000 0009
zmm24: 0000 00B2 0000 00CC 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 000E 0000 000D 0000 000C 0000 000B 0000 000A 0000 0009
zmm23: 0000 00B3 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 000E 0000 000D 0000 000C 0000 000B 0000 000A 0000 0009
END
Nasm::X86::BlockMultiWayTree::splitFullRightNode($bmt, $bs)
Split a full right node block held in 25..23 whose parent is in 31..29 and place the new left block in 25..23. The loop and length fields are assumed to be authoritative and hence are preserved.
Parameter Description
1 $bmt Block multi way tree descriptor
2 $bs Byte string locator
Example:
my $tk = Rd(1..12, 0, 0, 12, 0xC1);
my $td = Rd(1..12, 0, 0, 0, 0xC2);
my $tn = Rd(1, 0xBB, 3..13, 0, 0, 0xCC);
my $lk = Rd(17..30, 14, 0xA1);
my $ld = Rd(17..30, 0xCC, 0xA2);
my $ln = Rd(17..31, 0xAA);
my $rk = Rd(17..30, 14, 0xB1);
my $rd = Rd(17..30, 0xCC, 0xB2);
my $rn = Rd(17..31, 0xBB);
my $b = CreateByteString;
my $t = $b->CreateBlockMultiWayTree;
Vmovdqu8 zmm31, "[$tk]";
Vmovdqu8 zmm30, "[$td]";
Vmovdqu8 zmm29, "[$tn]";
Vmovdqu8 zmm28, "[$lk]";
Vmovdqu8 zmm27, "[$ld]";
Vmovdqu8 zmm26, "[$ln]";
Vmovdqu8 zmm25, "[$rk]";
Vmovdqu8 zmm24, "[$rd]";
Vmovdqu8 zmm23, "[$rn]";
$t->splitFullRightNode($b->bs);
PrintOutRegisterInHex reverse zmm(23..31);
ok Assemble(debug => 0, eq => <<END);
zmm31: 0000 00C1 0000 000D 0000 0000 0000 000C 0000 000B 0000 000A 0000 0009 0000 0008 0000 0007 0000 0006 0000 0005 0000 0004 0000 0003 0000 0002 0000 0018 0000 0001
zmm30: 0000 00C2 0000 0000 0000 0000 0000 000C 0000 000B 0000 000A 0000 0009 0000 0008 0000 0007 0000 0006 0000 0005 0000 0004 0000 0003 0000 0002 0000 0018 0000 0001
zmm29: 0000 00CC 0000 0000 0000 000D 0000 000C 0000 000B 0000 000A 0000 0009 0000 0008 0000 0007 0000 0006 0000 0005 0000 0004 0000 0003 0000 00BB 0000 00AA 0000 0001
zmm28: 0000 00A1 0000 0007 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0017 0000 0016 0000 0015 0000 0014 0000 0013 0000 0012 0000 0011
zmm27: 0000 00A2 0000 00CC 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0017 0000 0016 0000 0015 0000 0014 0000 0013 0000 0012 0000 0011
zmm26: 0000 00AA 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0017 0000 0016 0000 0015 0000 0014 0000 0013 0000 0012 0000 0011
zmm25: 0000 00B1 0000 0006 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 001E 0000 001D 0000 001C 0000 001B 0000 001A 0000 0019
zmm24: 0000 00B2 0000 00CC 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 001E 0000 001D 0000 001C 0000 001B 0000 001A 0000 0019
zmm23: 0000 00BB 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 001E 0000 001D 0000 001C 0000 001B 0000 001A 0000 0019
END
Nasm::X86::BlockMultiWayTree::findAndSplit($bmt, @variables)
Find a key in a tree which is known to contain at least one key splitting full nodes along the path to the key.
Parameter Description
1 $bmt Block multi way tree descriptor
2 @variables Variables
LocateIntelEmulator()
Locate the Intel Software Development Emulator
removeNonAsciiChars($string)
Return a copy of the specified string with all the non ascii characters removed
Parameter Description
1 $string String
totalBytesAssembled()
Total size in bytes of all files assembled during testing
Index
1 All8Structure - Create a structure consisting of 8 byte fields
2 AllocateAll8OnStack - Create a local data descriptor consisting of the specified number of 8 byte local variables and return an array: (local data descriptor, variable definitions.
3 AllocateMemory - Allocate the specified amount of memory via mmap and return its address
4 Assemble - Assemble the generated code
5 CallC - Call a C subroutine
6 ClassifyCharacters4 - Classify the utf32 characters in a block of memory of specified length using zmm0 formatted in double words with each word having the classification in the highest 8 bits and the utf32 character in the lower 21 bits.
7 ClassifyInRange - Classify the utf32 characters in a block of memory of specified length using zmm0, zmm1 formatted in double words with each word in zmm1 having the classification in the highest 8 bits and with zmm0 and zmm1 having the utf32 character at the start (zmm0) and end (zmm1) of each range in the lower 21 bits.
8 ClassifyRange - Implementation of ClassifyInRange and ClassifyWithinRange
9 ClassifyWithInRange - Classify the utf32 characters in a block of memory of specified length using zmm0, zmm1 formatted in double words with the classification range in the highest 8 bits of zmm0 and zmm1 and the utf32 character at the start (zmm0) and end (zmm1) of each range in the lower 21 bits.
10 ClearMemory - Clear memory - the address of the memory is in rax, the length in rdi
11 ClearRegisters - Clear registers by setting them to zero
12 ClearZF - Clear the zero flag
13 CloseFile - Close the file whose descriptor is in rax
14 Comment - Insert a comment into the assembly code
15 ConcatenateShortStrings - Concatenate the numbered source zmm containing a short string with the short string in the numbered target zmm.
16 ConvertUtf8ToUtf32 - Convert a string of utf8 to an allocated block of utf32 and return its address and length.
17 CopyMemory - Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
18 Cq - Define a quad constant
19 cr - Call a subroutine with a reordering of the registers.
20 CreateByteString - Create an relocatable string of bytes in an arena and returns its address in rax.
21 Cstrlen - Length of the C style string addressed by rax returning the length in r15
22 Db - Layout bytes in the data segment and return their label
23 Dbwdq - Layout data
24 DComment - Insert a comment into the data segment
25 Dd - Layout double words in the data segment and return their label
26 Dq - Layout quad words in the data segment and return their label
27 Ds - Layout bytes in memory and return their label
28 Dw - Layout words in the data segment and return their label
29 Else - Else body for an If statement
30 executeFileViaBash - Execute the file named in the byte string addressed by rax with bash
31 Exit - Exit with the specified return code or zero if no return code supplied.
32 Extern - Name external references
33 Float32 - 32 bit float
34 Float64 - 64 bit float
35 For - For - iterate the body as long as register is less than limit incrementing by increment each time
36 ForEver - Iterate for ever
37 ForIn - For - iterate the full body as long as register plus increment is less than than limit incrementing by increment each time then increment the last body for the last non full block.
38 Fork - Fork
39 FreeMemory - Free memory
40 getBFromXmm - Get the byte from the numbered xmm register and return it in a variable
41 getBFromZmm - Get the byte from the numbered zmm register and return it in a variable
42 getBwdqFromMm - Get the numbered byte|word|double word|quad word from the numbered zmm register and return it in a variable
43 getDFromXmm - Get the double word from the numbered xmm register and return it in a variable
44 getDFromZmm - Get the double word from the numbered zmm register and return it in a variable
45 GetLengthOfShortString - Get the length of the short string held in the numbered zmm register into the specified register
46 GetNextUtf8CharAsUtf32 - Get the next utf8 encoded character from the addressed memory and return it as a utf32 char
47 GetPid - Get process identifier
48 GetPidInHex - Get process identifier in hex as 8 zero terminated bytes in rax
49 GetPPid - Get parent process identifier
50 getQFromXmm - Get the quad word from the numbered xmm register and return it in a variable
51 getQFromZmm - Get the quad word from the numbered zmm register and return it in a variable
52 GetUid - Get userid of current process
53 getWFromXmm - Get the word from the numbered xmm register and return it in a variable
54 getWFromZmm - Get the word from the numbered zmm register and return it in a variable
55 Hash - Hash a string addressed by rax with length held in rdi and return the hash code in r15
56 hexTranslateTable - Create/address a hex translate table and return its label
57 If - If
58 IfEq - If equal execute the then body else the else body
59 IfGe - If greater than or equal execute the then body else the else body
60 IfGt - If greater than execute the then body else the else body
61 IfLe - If less than or equal execute the then body else the else body
62 IfLt - If less than execute the then body else the else body
63 IfNe - If not equal execute the then body else the else body
64 IfNz - If the zero is not set then execute the then body else the else body
65 IfZ - If the zero is set then execute the then body else the else body
66 Keep - Mark free registers so that they are not updated until we Free them or complain if the register is already in use.
67 KeepFree - Free registers so that they can be reused
68 KeepPop - Reset the status of the specified registers to the status quo ante the last push
69 KeepPush - Push the current status of the specified registers and then mark them as free
70 KeepReturn - Pop the specified register and mark it as in use to effect a subroutine return with this register.
71 KeepSet - Confirm that the specified registers are in use
72 Label - Create a unique label
73 Link - Libraries to link with
74 LoadConstantIntoMaskRegister - Load a constant into a mask register
75 LoadShortStringFromMemoryToZmm - Load the short string addressed by rax into the zmm register with the specified number
76 LoadShortStringFromMemoryToZmm2 - Load the short string addressed by rax into the zmm register with the specified number
77 LocalData - Map local data
78 LocateIntelEmulator - Locate the Intel Software Development Emulator
79 Macro - Create a sub with optional parameters name=> the name of the subroutine so it can be reused rather than regenerated, comment=> a comment describing the sub
80 MaskMemory - Write the specified byte into locations in the target mask that correspond to the locations in the source that contain the specified byte.
81 MaskMemoryInRange4 - Write the specified byte into locations in the target mask that correspond to the locations in the source that contain 4 bytes in the specified range.
82 MatchBrackets - Replace a utf32 character with 24 bits of offset to the matching opening or closing bracket.
83 Nasm::X86::BlockArray::address - Address of a block string
84 Nasm::X86::BlockArray::allocBlock - Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
85 Nasm::X86::BlockArray::dump - Dump a block array
86 Nasm::X86::BlockArray::get - Get an element from the array
87 Nasm::X86::BlockArray::pop - Pop an element from an array
88 Nasm::X86::BlockArray::push - Push an element onto the array
89 Nasm::X86::BlockArray::put - Put an element into an array as long as it is with in its limits established by pushing.
90 Nasm::X86::BlockMultiWayTree::address - Address of the byte string containing a block multi way tree
91 Nasm::X86::BlockMultiWayTree::allocBlock - Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
92 Nasm::X86::BlockMultiWayTree::allocKeysDataNode - Allocate a keys/data/node block and place it in the numbered zmm registers
93 Nasm::X86::BlockMultiWayTree::by - Call the specified body with each (key, data) from the specified tree in order
94 Nasm::X86::BlockMultiWayTree::depth - Return the depth of a node within a tree.
95 Nasm::X86::BlockMultiWayTree::find - Find a key in a tree and return its associated data
96 Nasm::X86::BlockMultiWayTree::findAndSplit - Find a key in a tree which is known to contain at least one key splitting full nodes along the path to the key.
97 Nasm::X86::BlockMultiWayTree::getKeysData - Load the keys and data blocks for a node
98 Nasm::X86::BlockMultiWayTree::getKeysDataNode - Load the keys, data and child nodes for a node
99 Nasm::X86::BlockMultiWayTree::getLengthInKeys - Get the length of the keys block in the numbered zmm and return it as a variable
100 Nasm::X86::BlockMultiWayTree::getLoop - Return the value of the loop field as a variable
101 Nasm::X86::BlockMultiWayTree::getNode - Load the child nodes for a node
102 Nasm::X86::BlockMultiWayTree::getUpFromData - Get the up offset from the data block in the numbered zmm and return it as a variable
103 Nasm::X86::BlockMultiWayTree::insert - Insert a (key, data) pair into the tree
104 Nasm::X86::BlockMultiWayTree::iterator - Iterate through a multi way tree
105 Nasm::X86::BlockMultiWayTree::Iterator::next - Next element in the tree
106 Nasm::X86::BlockMultiWayTree::leftMost - Return the left most node
107 Nasm::X86::BlockMultiWayTree::leftOrRightMost - Return the left most or right most node
108 Nasm::X86::BlockMultiWayTree::nodeFromData - Load the the node block into the numbered zmm corresponding to the data block held in the numbered zmm.
109 Nasm::X86::BlockMultiWayTree::putKeysData - Save the key and data blocks for a node
110 Nasm::X86::BlockMultiWayTree::putKeysDataNode - Save the keys, data and child nodes for a node
111 Nasm::X86::BlockMultiWayTree::putLengthInKeys - Get the length of the block in the numbered zmm from the specified variable
112 Nasm::X86::BlockMultiWayTree::putLoop - Set the value of the loop field from a variable
113 Nasm::X86::BlockMultiWayTree::putUpIntoData - Put the offset of the parent keys block expressed as a variable into the numbered zmm
114 Nasm::X86::BlockMultiWayTree::reParent - Reparent the children of a node held in registers.
115 Nasm::X86::BlockMultiWayTree::rightMost - Return the right most node
116 Nasm::X86::BlockMultiWayTree::splitFullLeftNode - Split a full left node block held in 28.
117 Nasm::X86::BlockMultiWayTree::splitFullRightNode - Split a full right node block held in 25.
118 Nasm::X86::BlockMultiWayTree::splitFullRoot - Split a full root block held in 31.
119 Nasm::X86::BlockMultiWayTree::splitNode - Split a node given its offset in a byte string retaining the key being inserted in the node split while putting the remainder to the left or right.
120 Nasm::X86::BlockString::address - Address of a block string
121 Nasm::X86::BlockString::allocBlock - Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
122 Nasm::X86::BlockString::append - Append the specified content in memory to the specified block string
123 Nasm::X86::BlockString::clear - Clear the block by freeing all but the first block
124 Nasm::X86::BlockString::concatenate - Concatenate two block strings by appending a copy of the source to the target block string.
125 Nasm::X86::BlockString::deleteChar - Delete a character in a block string
126 Nasm::X86::BlockString::dump - Dump a block string to sysout
127 Nasm::X86::BlockString::getBlock - Get the block with the specified offset in the specified block string and return it in the numbered zmm
128 Nasm::X86::BlockString::getBlockLength - Get the block length of the numbered zmm and return it in a variable
129 Nasm::X86::BlockString::getCharacter - Get a character from a block string
130 Nasm::X86::BlockString::getNextAndPrevBlockOffsetFromZmm - Get the offsets of the next and previous blocks as variables from the specified zmm
131 Nasm::X86::BlockString::insertChar - Insert a character into a block string
132 Nasm::X86::BlockString::len - Find the length of a block string
133 Nasm::X86::BlockString::putBlock - Write the numbered zmm to the block at the specified offset in the specified byte string
134 Nasm::X86::BlockString::putNextandPrevBlockOffsetIntoZmm - Save next and prev offsets into a zmm representing a block
135 Nasm::X86::BlockString::setBlockLengthInZmm - Set the block length of the numbered zmm to the specified length
136 Nasm::X86::ByteString::allocate - Allocate the amount of space indicated in rdi in the byte string addressed by rax and return the offset of the allocation in the arena in rdi
137 Nasm::X86::ByteString::allocBlock - Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
138 Nasm::X86::ByteString::allocZmmBlock - Allocate a block to hold a zmm register in the specified byte string and return the offset of the block in a variable
139 Nasm::X86::ByteString::append - Append one byte string to another
140 Nasm::X86::ByteString::blockSize - Size of a block
141 Nasm::X86::ByteString::chain - Return a variable with the end point of a chain of double words in the byte string starting at the specified variable.
142 Nasm::X86::ByteString::char - Append a character expressed as a decimal number to the byte string addressed by rax
143 Nasm::X86::ByteString::clear - Clear the byte string addressed by rax
144 Nasm::X86::ByteString::CreateBlockArray - Create a block array in a byte string
145 Nasm::X86::ByteString::CreateBlockMultiWayTree - Create a block multi way tree in a byte string
146 Nasm::X86::ByteString::CreateBlockString - Create a string from a doubly link linked list of 64 byte blocks linked via 4 byte offsets in the byte string addressed by rax and return its descriptor
147 Nasm::X86::ByteString::dump - Dump details of a byte string
148 Nasm::X86::ByteString::firstFreeBlock - Create and load a variable with the first free block on the free block chain or zero if no such block in the given byte string
149 Nasm::X86::ByteString::freeBlock - Free a block in a byte string by placing it on the free chain
150 Nasm::X86::ByteString::getBlock - Get the block with the specified offset in the specified block string and return it in the numbered zmm
151 Nasm::X86::ByteString::length - Get the length of a byte string
152 Nasm::X86::ByteString::m - Append the content with length rdi addressed by rsi to the byte string addressed by rax
153 Nasm::X86::ByteString::makeReadOnly - Make a byte string read only
154 Nasm::X86::ByteString::makeWriteable - Make a byte string writable
155 Nasm::X86::ByteString::nl - Append a new line to the byte string addressed by rax
156 Nasm::X86::ByteString::out - Print the specified byte string addressed by rax on sysout
157 Nasm::X86::ByteString::putBlock - Write the numbered zmm to the block at the specified offset in the specified byte string
158 Nasm::X86::ByteString::putChain - Write the double word in the specified variable to the double word location at the the specified offset in the specified byte string.
159 Nasm::X86::ByteString::q - Append a constant string to the byte string
160 Nasm::X86::ByteString::ql - Append a quoted string containing new line characters to the byte string addressed by rax
161 Nasm::X86::ByteString::read - Read the named file (terminated with a zero byte) and place it into the named byte string.
162 Nasm::X86::ByteString::setFirstFreeBlock - Set the first free block field from a variable
163 Nasm::X86::ByteString::updateSpace - Make sure that the byte string addressed by rax has enough space to accommodate content of length rdi
164 Nasm::X86::ByteString::write - Write the content in a byte string addressed by rax to a temporary file and replace the byte string content with the name of the temporary file
165 Nasm::X86::ByteString::z - Append a trailing zero to the byte string addressed by rax
166 Nasm::X86::LocalData::allocate8 - Add some 8 byte local variables and return an array of variable definitions
167 Nasm::X86::LocalData::free - Free a local data area on the stack
168 Nasm::X86::LocalData::start - Start a local data area on the stack
169 Nasm::X86::LocalData::variable - Add a local variable
170 Nasm::X86::LocalVariable::stack - Address a local variable on the stack
171 Nasm::X86::Scope::contains - Check that the named parent scope contains the specified child scope.
172 Nasm::X86::Scope::currentlyVisible - Check that the named parent scope is currently visible
173 Nasm::X86::Structure::field - Add a field of the specified length with an optional comment
174 Nasm::X86::StructureField::addr - Address a field in a structure by either the default register or the named register
175 Nasm::X86::Sub::call - Call a sub passing it some parameters
176 Nasm::X86::Variable::add - Add the right hand variable to the left hand variable and return the result as a new variable
177 Nasm::X86::Variable::address - Get the address of a variable with an optional offset
178 Nasm::X86::Variable::allocateMemory - Allocate the specified amount of memory via mmap and return its address
179 Nasm::X86::Variable::and - And two variables
180 Nasm::X86::Variable::arithmetic - Return a variable containing the result of an arithmetic operation on the left hand and right hand side variables
181 Nasm::X86::Variable::assign - Assign to the left hand side the value of the right hand side
182 Nasm::X86::Variable::boolean - Combine the left hand variable with the right hand variable via a boolean operator
183 Nasm::X86::Variable::clearMaskBit - Clear a bit in the specified mask register retaining the other bits
184 Nasm::X86::Variable::clearMemory - Clear the memory described in this variable
185 Nasm::X86::Variable::clone - Clone a variable to create a new variable
186 Nasm::X86::Variable::copy - Copy one variable into another
187 Nasm::X86::Variable::copyAddress - Copy a reference to a variable
188 Nasm::X86::Variable::copyMemory - Copy from one block of memory to another
189 Nasm::X86::Variable::debug - Dump the value of a variable on stdout with an indication of where the dump came from
190 Nasm::X86::Variable::dec - Decrement a variable
191 Nasm::X86::Variable::divide - Divide the left hand variable by the right hand variable and return the result as a new variable
192 Nasm::X86::Variable::division - Return a variable containing the result or the remainder that occurs when the left hand side is divided by the right hand side
193 Nasm::X86::Variable::dump - Dump the value of a variable to the specified channel adding an optional title and new line if requested
194 Nasm::X86::Variable::eq - Check whether the left hand variable is equal to the right hand variable
195 Nasm::X86::Variable::equals - Equals operator
196 Nasm::X86::Variable::err - Dump the value of a variable on stderr
197 Nasm::X86::Variable::errNL - Dump the value of a variable on stderr and append a new line
198 Nasm::X86::Variable::for - Iterate the body limit times.
199 Nasm::X86::Variable::freeMemory - Free the memory addressed by this variable for the specified length
200 Nasm::X86::Variable::ge - Check whether the left hand variable is greater than or equal to the right hand variable
201 Nasm::X86::Variable::getBFromZmm - Get the byte from the numbered zmm register and put it in a variable
202 Nasm::X86::Variable::getConst - Load the variable from a constant in effect setting a variable to a specified value
203 Nasm::X86::Variable::getDFromZmm - Get the double word from the numbered zmm register and put it in a variable
204 Nasm::X86::Variable::getQFromZmm - Get the quad word from the numbered zmm register and put it in a variable
205 Nasm::X86::Variable::getReg - Load the variable from the named registers
206 Nasm::X86::Variable::getWFromZmm - Get the word from the numbered zmm register and put it in a variable
207 Nasm::X86::Variable::gt - Check whether the left hand variable is greater than the right hand variable
208 Nasm::X86::Variable::inc - Increment a variable
209 Nasm::X86::Variable::incDec - Increment or decrement a variable
210 Nasm::X86::Variable::isRef - Check whether the specified variable is a reference to another variable
211 Nasm::X86::Variable::le - Check whether the left hand variable is less than or equal to the right hand variable
212 Nasm::X86::Variable::loadZmm - Load bytes from the memory addressed by the specified source variable into the numbered zmm register.
213 Nasm::X86::Variable::lt - Check whether the left hand variable is less than the right hand variable
214 Nasm::X86::Variable::max - Maximum of two variables
215 Nasm::X86::Variable::min - Minimum of two variables
216 Nasm::X86::Variable::minusAssign - Implement minus and assign
217 Nasm::X86::Variable::mod - Divide the left hand variable by the right hand variable and return the remainder as a new variable
218 Nasm::X86::Variable::ne - Check whether the left hand variable is not equal to the right hand variable
219 Nasm::X86::Variable::or - Or two variables
220 Nasm::X86::Variable::out - Dump the value of a variable on stdout
221 Nasm::X86::Variable::outNL - Dump the value of a variable on stdout and append a new line
222 Nasm::X86::Variable::plusAssign - Implement plus and assign
223 Nasm::X86::Variable::pop - Pop a variable from the stack
224 Nasm::X86::Variable::printErrMemoryInHexNL - Write the memory addressed by a variable to stderr
225 Nasm::X86::Variable::printMemoryInHexNL - Write the memory addressed by a variable to stdout or stderr
226 Nasm::X86::Variable::printOutMemoryInHexNL - Write the memory addressed by a variable to stdout
227 Nasm::X86::Variable::push - Push a variable onto the stack
228 Nasm::X86::Variable::putBIntoXmm - Place the value of the content variable at the byte in the numbered xmm register
229 Nasm::X86::Variable::putBIntoZmm - Place the value of the content variable at the byte in the numbered zmm register
230 Nasm::X86::Variable::putBwdqIntoMm - Place the value of the content variable at the byte|word|double word|quad word in the numbered zmm register
231 Nasm::X86::Variable::putDIntoXmm - Place the value of the content variable at the double word in the numbered xmm register
232 Nasm::X86::Variable::putDIntoZmm - Place the value of the content variable at the double word in the numbered zmm register
233 Nasm::X86::Variable::putQIntoXmm - Place the value of the content variable at the quad word in the numbered xmm register
234 Nasm::X86::Variable::putQIntoZmm - Place the value of the content variable at the quad word in the numbered zmm register
235 Nasm::X86::Variable::putWIntoXmm - Place the value of the content variable at the word in the numbered xmm register
236 Nasm::X86::Variable::putWIntoZmm - Place the value of the content variable at the word in the numbered zmm register
237 Nasm::X86::Variable::saveZmm2222 - Save bytes into the memory addressed by the target variable from the numbered zmm register.
238 Nasm::X86::Variable::setMask - Set the mask register to ones starting at the specified position for the specified length and zeroes elsewhere
239 Nasm::X86::Variable::setMaskBit - Set a bit in the specified mask register retaining the other bits
240 Nasm::X86::Variable::setMaskFirst - Set the first bits in the specified mask register
241 Nasm::X86::Variable::setReg - Set the named registers from the content of the variable
242 Nasm::X86::Variable::setZmm - Load bytes from the memory addressed by specified source variable into the numbered zmm register at the offset in the specified offset moving the number of bytes in the specified variable
243 Nasm::X86::Variable::str - The name of the variable
244 Nasm::X86::Variable::sub - Subtract the right hand variable from the left hand variable and return the result as a new variable
245 Nasm::X86::Variable::times - Multiply the left hand variable by the right hand variable and return the result as a new variable
246 Nasm::X86::Variable::zBroadCastD - Broadcast a double word in a variable into the numbered zmm.
247 OpenRead - Open a file, whose name is addressed by rax, for read and return the file descriptor in rax
248 OpenWrite - Create the file named by the terminated string addressed by rax for write
249 PeekR - Peek at register on stack
250 PopEax - We cannot pop a double word from the stack in 64 bit long mode using pop so we improvise
251 PopR - Pop registers from the stack
252 PopRR - Pop registers from the stack without tracking
253 PrintErrMemory - Print the memory addressed by rax for a length of rdi on stderr
254 PrintErrMemoryInHex - Dump memory from the address in rax for the length in rdi on stderr
255 PrintErrMemoryInHexNL - Dump memory from the address in rax for the length in rdi and then print a new line
256 PrintErrMemoryNL - Print the memory addressed by rax for a length of rdi followed by a new line on stderr
257 PrintErrNL - Print a new line to stderr
258 PrintErrRaxInHex - Write the content of register rax in hexadecimal in big endian notation to stderr
259 PrintErrRegisterInHex - Print the named registers as hex strings on stderr
260 PrintErrString - Print a constant string to stderr.
261 PrintErrStringNL - Print a constant string followed by a new line to stderr
262 PrintErrZF - Print the zero flag without disturbing it on stderr
263 PrintMemory - Print the memory addressed by rax for a length of rdi on the specified channel
264 PrintMemoryInHex - Dump memory from the address in rax for the length in rdi on the specified channel.
265 PrintNL - Print a new line to stdout or stderr
266 PrintOutMemory - Print the memory addressed by rax for a length of rdi on stdout
267 PrintOutMemoryInHex - Dump memory from the address in rax for the length in rdi on stdout
268 PrintOutMemoryInHexNL - Dump memory from the address in rax for the length in rdi and then print a new line
269 PrintOutMemoryNL - Print the memory addressed by rax for a length of rdi followed by a new line on stdout
270 PrintOutNL - Print a new line to stderr
271 PrintOutRaxInHex - Write the content of register rax in hexadecimal in big endian notation to stderr
272 PrintOutRaxInReverseInHex - Write the content of register rax to stderr in hexadecimal in little endian notation
273 PrintOutRegisterInHex - Print the named registers as hex strings on stdout
274 PrintOutRegistersInHex - Print the general purpose registers in hex
275 PrintOutRflagsInHex - Print the flags register in hex
276 PrintOutRipInHex - Print the instruction pointer in hex
277 PrintOutString - Print a constant string to stdout.
278 PrintOutStringNL - Print a constant string followed by a new line to stdout
279 PrintOutZF - Print the zero flag without disturbing it on stdout
280 PrintRaxInHex - Write the content of register rax in hexadecimal in big endian notation to the specified channel
281 PrintRegisterInHex - Print the named registers as hex strings
282 PrintString - Print a constant string to the specified channel
283 PushR - Push registers onto the stack
284 PushRR - Push registers onto the stack without tracking
285 Rb - Layout bytes in the data segment and return their label
286 Rbwdq - Layout data
287 RComment - Insert a comment into the read only data segment
288 Rd - Layout double words in the data segment and return their label
289 ReadFile - Read a file whose name is addressed by rax into memory.
290 ReadTimeStampCounter - Read the time stamp counter and return the time in nanoseconds in rax
291 RegisterSize - Return the size of a register
292 removeNonAsciiChars - Return a copy of the specified string with all the non ascii characters removed
293 ReorderSyscallRegisters - Map the list of registers provided to the 64 bit system call sequence
294 RestoreFirstFour - Restore the first 4 parameter registers
295 RestoreFirstFourExceptRax - Restore the first 4 parameter registers except rax so it can return its value
296 RestoreFirstFourExceptRaxAndRdi - Restore the first 4 parameter registers except rax and rdi so we can return a pair of values
297 RestoreFirstSeven - Restore the first 7 parameter registers
298 RestoreFirstSevenExceptRax - Restore the first 7 parameter registers except rax which is being used to return the result
299 RestoreFirstSevenExceptRaxAndRdi - Restore the first 7 parameter registers except rax and rdi which are being used to return the results
300 Rq - Layout quad words in the data segment and return their label
301 Rs - Layout bytes in read only memory and return their label
302 Rw - Layout words in the data segment and return their label
303 SaveFirstFour - Save the first 4 parameter registers making any parameter registers read only
304 SaveFirstSeven - Save the first 7 parameter registers
305 Scope - Create and stack a new scope and continue with it as the current scope
306 ScopeEnd - End the current scope and continue with the containing parent scope
307 SetLabel - Set a label in the code section
308 SetLengthOfShortString - Set the length of the short string held in the numbered zmm register into the specified register
309 SetMaskRegister - Set the mask register to ones starting at the specified position for the specified length and zeroes elsewhere
310 SetZF - Set the zero flag
311 Start - Initialize the assembler
312 StatSize - Stat a file whose name is addressed by rax to get its size in rax
313 Structure - Create a structure addressed by a register
314 Subroutine - Create a subroutine that can be called in assembler code
315 Then - Then body for an If statement
316 totalBytesAssembled - Total size in bytes of all files assembled during testing
317 Trace - Add tracing code
318 unlinkFile - Unlink the named file
319 UnReorderSyscallRegisters - Recover the initial values in registers that were reordered
320 Variable - Create a new variable with the specified size and name initialized via an expression
321 Vb - Define a byte variable
322 Vd - Define a double word variable
323 Vq - Define a quad variable
324 Vr - Define a reference variable
325 Vw - Define a word variable
326 Vx - Define an xmm variable
327 VxyzInit - Initialize an xyz register from general purpose registers
328 Vy - Define an ymm variable
329 Vz - Define an zmm variable
330 WaitPid - Wait for the pid in rax to complete
331 xmm - Add xmm to the front of a list of register expressions
332 ymm - Add ymm to the front of a list of register expressions
333 zmm - Add zmm to the front of a list of register expressions
Installation
This module is written in 100% Pure Perl and, thus, it is easy to read, comprehend, use, modify and install via cpan:
sudo cpan install Nasm::X86
Author
Copyright
Copyright (c) 2016-2021 Philip R Brenan.
This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.