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 "20210727".
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;
Rutf8(@d)
Layout a utf8 encoded string as bytes in read only memory and return their label
Parameter Description
1 @d Data to be laid out
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 registers as in use so that they cannot be updated until we explicitly free them. 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
Block($body)
Execute a block of code one with the option of jumping out of the block or restarting the block via the supplied labels.
Parameter Description
1 $body Body
Example:
Mov rax, 0;
Block # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
{my ($start, $end) = @_;
PrintOutRegisterInHex rax;
Cmp rax, 3;
IfGe {Jmp $end};
Inc rax;
PrintOutRegisterInHex rax
Jmp $start;
};
ok Assemble(debug => 0, eq => <<END);
rax: 0000 0000 0000 0000
rax: 0000 0000 0000 0001
rax: 0000 0000 0000 0002
rax: 0000 0000 0000 0003
END
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 # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
{my ($start, $end, $next) = @_;
Cmp rax, 3;
IfGe {Jmp $end};
PrintOutRegisterInHex rax;
} rax, 16, 1;
ok Assemble(debug => 0, eq => <<END);
rax: 0000 0000 0000 0000
rax: 0000 0000 0000 0001
rax: 0000 0000 0000 0002
END
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) # 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);
# Single character classifications
Cq('newLine', 0x0A)->putBIntoZmm(0, 0); #r 0x0 - open bracket #r 0x1 - close bracket
Cq('newLine', 0x02)->putBIntoZmm(0, 3); #r 0x2 - new line, #r 0x3 - new line acting as a semi-colon
Cq('space', 0x20)->putBIntoZmm(0, 4);
Cq('space', 0x05)->putBIntoZmm(0, 7); #r 0x5 - space
my sub pu32($$) # Print some utf32 characters
{my ($n, $m) = @_; # Variable: number of characters to print, variable: address of memory
$n->for(sub
{my ($index, $start, $next, $end) = @_;
my $a = $m + $index * 4;
$a->setReg(r15);
KeepFree r15;
Mov r15d, "[r15]";
KeepFree r15;
PrintOutRegisterInHex r15;
});
}
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";
pu32($s, $t);
}
# circledLatinLetter : assign ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ
# mathematicalBold : dyad lr 3 𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚺𝚻𝚼𝚽𝚾𝚿𝛀𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛔𝛕𝛖𝛗𝛘𝛙𝛚𝟊𝟋
# mathematicalBoldFraktur : 𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟
# mathematicalBoldItalic : prefix 𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜮𝜯𝜰𝜱𝜲𝜳𝜴𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝈𝝉𝝊𝝋𝝌𝝍𝝎
# mathematicalBoldScript : 𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃
# mathematicalDouble-struck : 𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫
# mathematicalFraktur : 𝔄𝔅𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷
# mathematicalItalic : 𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛴𝛵𝛶𝛷𝛸𝛹𝛺𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜎𝜏𝜐𝜑𝜒𝜓𝜔
# mathematicalMonospace : 𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣
# mathematicalSans-serif : variable 𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓
# mathematicalSans-serifBold : 𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝨𝝩𝝪𝝫𝝬𝝭𝝮𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞂𝞃𝞄𝞅𝞆𝞇𝞈
# mathematicalSans-serifBoldItalic : postfix 𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞢𝞣𝞤𝞥𝞦𝞧𝞨𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞼𝞽𝞾𝞿𝟀𝟁𝟂
# mathematicalSans-serifItalic : 𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻
# mathematicalScript : 𝒜𝒞𝒟𝒢𝒥𝒦𝒩𝒪𝒫𝒬𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵𝒶𝒷𝒸𝒹𝒻𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏
# negativeCircledLatinLetter : 🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩
# negativeSquaredLatinLetter : 🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉
# squaredLatinLetter : 🄰🄱🄲🄳🄴🄵🄶🄷🄸🄹🄺🄻🄼🄽🄾🄿🅀🅁🅂🅃🅄🅅🅆🅇🅈🅉🆥
# semiColon : semicolon ⟢
# Delete following code when the following test is completed
if (0) # Convert utf8 test string to utf32
{my @p = my ($u32, $size32, $count) = (Vq(u32), Vq(size32), Vq(count));
ClassifyCharacters4 address=>$u32, size=>$count;
PrintOutStringNL "Convert test statement - special characters";
pu32($count, $u32);
Cq('variable', 0x0) ->putDIntoZmm(0, 0); # Range classifications
Cq('variable', 0x06) ->putBIntoZmm(0, 3); #r 0x6 - ascii
Cq('variable', 0x01D5A0)->putDIntoZmm(0, 4);
Cq('variable', 0x07) ->putBIntoZmm(0, 7); #r 0x7 - variable
Cq('variable', 0x01D434)->putDIntoZmm(0, 8);
Cq('variable', 0x08) ->putBIntoZmm(0, 11); #r 0x8 - assign
Cq('variable', 0x01D400)->putDIntoZmm(0, 12);
Cq('variable', 0x09) ->putBIntoZmm(0, 15); #r 0x9 -
Cq('variable', 0x7f) ->putDIntoZmm(1, 0);
Cq('variable', 0x06) ->putBIntoZmm(1, 3);
Cq('variable', 0x01D5D3)->putDIntoZmm(1, 4);
Cq('variable', 0x07) ->putBIntoZmm(1, 7);
Cq('variable', 0x01D467)->putDIntoZmm(1, 8);
Cq('variable', 0x08) ->putBIntoZmm(1, 11);
Cq('variable', 0x01D433)->putDIntoZmm(1, 12);
Cq('variable', 0x09) ->putBIntoZmm(1, 15);
ClassifyInRange address=>$u32, size=>$count;
PrintOutStringNL "Convert test statement - ranges";
pu32($count, $u32);
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";
pu32($count, $u32);
MatchBrackets address=>$u32, size=>$count, $opens, $fail;
PrintOutStringNL "Convert test statement - bracket matching";
pu32($count, $u32);
}
$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 0500 0020
r15: 0000 0000 0001 D44E
r15: 0000 0000 0200 000A
r15: 0000 0000 0001 D5BB
r15: 0000 0000 0001 D429
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 the classification held in zmm0: zmm0 should be formatted in double words with each word having the classification in the highest 8 bits and the utf32 character so classified in the lower 21 bits. The classification bits are copied into the high unused) byte of each utf32 character in the block of memory.
Parameter Description
1 @parameters Parameters
ClassifyInRange(@parameters)
Character classification: classify the utf32 characters in a block of memory of specified length using a range specification held in 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 the high (unused) byte of each utf32 character in the block of memory.
Parameter Description
1 @parameters Parameters
ClassifyWithInRange(@parameters)
Bracket classification: Classify the utf32 characters in a block of memory of specified length using a range specification held in 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 the high (unused) byte of each utf32 character in the block of memory.
Parameter Description
1 @parameters Parameters
ClassifyWithInRangeAndSaveOffset(@parameters)
Alphabetic classification: classify the utf32 characters in a block of memory of specified length using a range specification held in zmm0, zmm1 formatted in double words with the classification code in the high byte of zmm1 and the offset of the first element in the range in the high byte of zmm0. The lowest 21 bits of each double word in zmm0 and zmm1 contain the utf32 characters marking the start and end of each range. The classification bits from zmm1 for the first matching range are copied into the high byte of each utf32 character in the block of memory. The offset in the range is copied into the lowest byte of each utf32 character in the block of memory. The middle two bytes are cleared. The net effect is to reduce 21 bits of utf32 to 16 bits.
Parameter Description
1 @parameters Parameters
MatchBrackets(@parameters)
Replace the low three bytes of a utf32 bracket 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
PrintUtf32($n, $m)
Print the specified number of utf32 characters at the specified address
Parameter Description
1 $n Variable: number of characters to print
2 $m Variable: address of memory
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
StringLength(@parameters)
Length of a zero terminated string
Parameter Description
1 @parameters Parameters
Example:
StringLength(Vq(string, Rs("abcd")))->outNL; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Assemble(debug => 0, eq => <<END);
size: 0000 0000 0000 0004
END
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 classification in high byte if 1 else in classification if 2
2 @parameters Parameters
Cstrlen()
Length of the C style string addressed by rax returning the length in r15
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 Block - Execute a block of code one with the option of jumping out of the block or restarting the block via the supplied labels.
6 CallC - Call a C subroutine
7 ClassifyCharacters4 - Classify the utf32 characters in a block of memory of specified length using the classification held in zmm0: zmm0 should be formatted in double words with each word having the classification in the highest 8 bits and the utf32 character so classified in the lower 21 bits.
8 ClassifyInRange - Character classification: classify the utf32 characters in a block of memory of specified length using a range specification held in 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.
9 ClassifyRange - Implementation of ClassifyInRange and ClassifyWithinRange
10 ClassifyWithInRange - Bracket classification: Classify the utf32 characters in a block of memory of specified length using a range specification held in 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.
11 ClassifyWithInRangeAndSaveOffset - Alphabetic classification: classify the utf32 characters in a block of memory of specified length using a range specification held in zmm0, zmm1 formatted in double words with the classification code in the high byte of zmm1 and the offset of the first element in the range in the high byte of zmm0.
12 ClearMemory - Clear memory - the address of the memory is in rax, the length in rdi
13 ClearRegisters - Clear registers by setting them to zero
14 ClearZF - Clear the zero flag
15 CloseFile - Close the file whose descriptor is in rax
16 Comment - Insert a comment into the assembly code
17 ConcatenateShortStrings - Concatenate the numbered source zmm containing a short string with the short string in the numbered target zmm.
18 ConvertUtf8ToUtf32 - Convert a string of utf8 to an allocated block of utf32 and return its address and length.
19 CopyMemory - Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
20 Cq - Define a quad constant
21 cr - Call a subroutine with a reordering of the registers.
22 CreateByteString - Create an relocatable string of bytes in an arena and returns its address in rax.
23 Cstrlen - Length of the C style string addressed by rax returning the length in r15
24 Db - Layout bytes in the data segment and return their label
25 Dbwdq - Layout data
26 DComment - Insert a comment into the data segment
27 Dd - Layout double words in the data segment and return their label
28 Dq - Layout quad words in the data segment and return their label
29 Ds - Layout bytes in memory and return their label
30 Dw - Layout words in the data segment and return their label
31 Else - Else body for an If statement
32 executeFileViaBash - Execute the file named in the byte string addressed by rax with bash
33 Exit - Exit with the specified return code or zero if no return code supplied.
34 Extern - Name external references
35 Float32 - 32 bit float
36 Float64 - 64 bit float
37 For - For - iterate the body as long as register is less than limit incrementing by increment each time
38 ForEver - Iterate for ever
39 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.
40 Fork - Fork
41 FreeMemory - Free memory
42 getBFromXmm - Get the byte from the numbered xmm register and return it in a variable
43 getBFromZmm - Get the byte from the numbered zmm register and return it in a variable
44 getBwdqFromMm - Get the numbered byte|word|double word|quad word from the numbered zmm register and return it in a variable
45 getDFromXmm - Get the double word from the numbered xmm register and return it in a variable
46 getDFromZmm - Get the double word from the numbered zmm register and return it in a variable
47 GetLengthOfShortString - Get the length of the short string held in the numbered zmm register into the specified register
48 GetNextUtf8CharAsUtf32 - Get the next utf8 encoded character from the addressed memory and return it as a utf32 char
49 GetPid - Get process identifier
50 GetPidInHex - Get process identifier in hex as 8 zero terminated bytes in rax
51 GetPPid - Get parent process identifier
52 getQFromXmm - Get the quad word from the numbered xmm register and return it in a variable
53 getQFromZmm - Get the quad word from the numbered zmm register and return it in a variable
54 GetUid - Get userid of current process
55 getWFromXmm - Get the word from the numbered xmm register and return it in a variable
56 getWFromZmm - Get the word from the numbered zmm register and return it in a variable
57 Hash - Hash a string addressed by rax with length held in rdi and return the hash code in r15
58 hexTranslateTable - Create/address a hex translate table and return its label
59 If - If
60 IfEq - If equal execute the then body else the else body
61 IfGe - If greater than or equal execute the then body else the else body
62 IfGt - If greater than execute the then body else the else body
63 IfLe - If less than or equal execute the then body else the else body
64 IfLt - If less than execute the then body else the else body
65 IfNe - If not equal execute the then body else the else body
66 IfNz - If the zero is not set then execute the then body else the else body
67 IfZ - If the zero is set then execute the then body else the else body
68 Keep - Mark registers as in use so that they cannot be updated until we explicitly free them.
69 KeepFree - Free registers so that they can be reused
70 KeepPop - Reset the status of the specified registers to the status quo ante the last push
71 KeepPush - Push the current status of the specified registers and then mark them as free
72 KeepReturn - Pop the specified register and mark it as in use to effect a subroutine return with this register.
73 KeepSet - Confirm that the specified registers are in use
74 Label - Create a unique label
75 Link - Libraries to link with
76 LoadConstantIntoMaskRegister - Load a constant into a mask register
77 LoadShortStringFromMemoryToZmm - Load the short string addressed by rax into the zmm register with the specified number
78 LoadShortStringFromMemoryToZmm2 - Load the short string addressed by rax into the zmm register with the specified number
79 LocalData - Map local data
80 LocateIntelEmulator - Locate the Intel Software Development Emulator
81 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
82 MaskMemory - Write the specified byte into locations in the target mask that correspond to the locations in the source that contain the specified byte.
83 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.
84 MatchBrackets - Replace the low three bytes of a utf32 bracket character with 24 bits of offset to the matching opening or closing bracket.
85 Nasm::X86::BlockArray::address - Address of a block string
86 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
87 Nasm::X86::BlockArray::dump - Dump a block array
88 Nasm::X86::BlockArray::get - Get an element from the array
89 Nasm::X86::BlockArray::pop - Pop an element from an array
90 Nasm::X86::BlockArray::push - Push an element onto the array
91 Nasm::X86::BlockArray::put - Put an element into an array as long as it is with in its limits established by pushing.
92 Nasm::X86::BlockMultiWayTree::address - Address of the byte string containing a block multi way tree
93 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
94 Nasm::X86::BlockMultiWayTree::allocKeysDataNode - Allocate a keys/data/node block and place it in the numbered zmm registers
95 Nasm::X86::BlockMultiWayTree::by - Call the specified body with each (key, data) from the specified tree in order
96 Nasm::X86::BlockMultiWayTree::depth - Return the depth of a node within a tree.
97 Nasm::X86::BlockMultiWayTree::find - Find a key in a tree and return its associated data
98 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.
99 Nasm::X86::BlockMultiWayTree::getKeysData - Load the keys and data blocks for a node
100 Nasm::X86::BlockMultiWayTree::getKeysDataNode - Load the keys, data and child nodes for a node
101 Nasm::X86::BlockMultiWayTree::getLengthInKeys - Get the length of the keys block in the numbered zmm and return it as a variable
102 Nasm::X86::BlockMultiWayTree::getLoop - Return the value of the loop field as a variable
103 Nasm::X86::BlockMultiWayTree::getNode - Load the child nodes for a node
104 Nasm::X86::BlockMultiWayTree::getUpFromData - Get the up offset from the data block in the numbered zmm and return it as a variable
105 Nasm::X86::BlockMultiWayTree::insert - Insert a (key, data) pair into the tree
106 Nasm::X86::BlockMultiWayTree::iterator - Iterate through a multi way tree
107 Nasm::X86::BlockMultiWayTree::Iterator::next - Next element in the tree
108 Nasm::X86::BlockMultiWayTree::leftMost - Return the left most node
109 Nasm::X86::BlockMultiWayTree::leftOrRightMost - Return the left most or right most node
110 Nasm::X86::BlockMultiWayTree::nodeFromData - Load the the node block into the numbered zmm corresponding to the data block held in the numbered zmm.
111 Nasm::X86::BlockMultiWayTree::putKeysData - Save the key and data blocks for a node
112 Nasm::X86::BlockMultiWayTree::putKeysDataNode - Save the keys, data and child nodes for a node
113 Nasm::X86::BlockMultiWayTree::putLengthInKeys - Get the length of the block in the numbered zmm from the specified variable
114 Nasm::X86::BlockMultiWayTree::putLoop - Set the value of the loop field from a variable
115 Nasm::X86::BlockMultiWayTree::putUpIntoData - Put the offset of the parent keys block expressed as a variable into the numbered zmm
116 Nasm::X86::BlockMultiWayTree::reParent - Reparent the children of a node held in registers.
117 Nasm::X86::BlockMultiWayTree::rightMost - Return the right most node
118 Nasm::X86::BlockMultiWayTree::splitFullLeftNode - Split a full left node block held in 28.
119 Nasm::X86::BlockMultiWayTree::splitFullRightNode - Split a full right node block held in 25.
120 Nasm::X86::BlockMultiWayTree::splitFullRoot - Split a full root block held in 31.
121 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.
122 Nasm::X86::BlockString::address - Address of a block string
123 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
124 Nasm::X86::BlockString::append - Append the specified content in memory to the specified block string
125 Nasm::X86::BlockString::clear - Clear the block by freeing all but the first block
126 Nasm::X86::BlockString::concatenate - Concatenate two block strings by appending a copy of the source to the target block string.
127 Nasm::X86::BlockString::deleteChar - Delete a character in a block string
128 Nasm::X86::BlockString::dump - Dump a block string to sysout
129 Nasm::X86::BlockString::getBlock - Get the block with the specified offset in the specified block string and return it in the numbered zmm
130 Nasm::X86::BlockString::getBlockLength - Get the block length of the numbered zmm and return it in a variable
131 Nasm::X86::BlockString::getCharacter - Get a character from a block string
132 Nasm::X86::BlockString::getNextAndPrevBlockOffsetFromZmm - Get the offsets of the next and previous blocks as variables from the specified zmm
133 Nasm::X86::BlockString::insertChar - Insert a character into a block string
134 Nasm::X86::BlockString::len - Find the length of a block string
135 Nasm::X86::BlockString::putBlock - Write the numbered zmm to the block at the specified offset in the specified byte string
136 Nasm::X86::BlockString::putNextandPrevBlockOffsetIntoZmm - Save next and prev offsets into a zmm representing a block
137 Nasm::X86::BlockString::setBlockLengthInZmm - Set the block length of the numbered zmm to the specified length
138 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
139 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
140 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
141 Nasm::X86::ByteString::append - Append one byte string to another
142 Nasm::X86::ByteString::blockSize - Size of a block
143 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.
144 Nasm::X86::ByteString::char - Append a character expressed as a decimal number to the byte string addressed by rax
145 Nasm::X86::ByteString::clear - Clear the byte string addressed by rax
146 Nasm::X86::ByteString::CreateBlockArray - Create a block array in a byte string
147 Nasm::X86::ByteString::CreateBlockMultiWayTree - Create a block multi way tree in a byte string
148 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
149 Nasm::X86::ByteString::dump - Dump details of a byte string
150 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
151 Nasm::X86::ByteString::freeBlock - Free a block in a byte string by placing it on the free chain
152 Nasm::X86::ByteString::getBlock - Get the block with the specified offset in the specified block string and return it in the numbered zmm
153 Nasm::X86::ByteString::length - Get the length of a byte string
154 Nasm::X86::ByteString::m - Append the content with length rdi addressed by rsi to the byte string addressed by rax
155 Nasm::X86::ByteString::makeReadOnly - Make a byte string read only
156 Nasm::X86::ByteString::makeWriteable - Make a byte string writable
157 Nasm::X86::ByteString::nl - Append a new line to the byte string addressed by rax
158 Nasm::X86::ByteString::out - Print the specified byte string addressed by rax on sysout
159 Nasm::X86::ByteString::putBlock - Write the numbered zmm to the block at the specified offset in the specified byte string
160 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.
161 Nasm::X86::ByteString::q - Append a constant string to the byte string
162 Nasm::X86::ByteString::ql - Append a quoted string containing new line characters to the byte string addressed by rax
163 Nasm::X86::ByteString::read - Read the named file (terminated with a zero byte) and place it into the named byte string.
164 Nasm::X86::ByteString::setFirstFreeBlock - Set the first free block field from a variable
165 Nasm::X86::ByteString::updateSpace - Make sure that the byte string addressed by rax has enough space to accommodate content of length rdi
166 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
167 Nasm::X86::ByteString::z - Append a trailing zero to the byte string addressed by rax
168 Nasm::X86::LocalData::allocate8 - Add some 8 byte local variables and return an array of variable definitions
169 Nasm::X86::LocalData::free - Free a local data area on the stack
170 Nasm::X86::LocalData::start - Start a local data area on the stack
171 Nasm::X86::LocalData::variable - Add a local variable
172 Nasm::X86::LocalVariable::stack - Address a local variable on the stack
173 Nasm::X86::Scope::contains - Check that the named parent scope contains the specified child scope.
174 Nasm::X86::Scope::currentlyVisible - Check that the named parent scope is currently visible
175 Nasm::X86::Structure::field - Add a field of the specified length with an optional comment
176 Nasm::X86::StructureField::addr - Address a field in a structure by either the default register or the named register
177 Nasm::X86::Sub::call - Call a sub passing it some parameters
178 Nasm::X86::Variable::add - Add the right hand variable to the left hand variable and return the result as a new variable
179 Nasm::X86::Variable::address - Get the address of a variable with an optional offset
180 Nasm::X86::Variable::allocateMemory - Allocate the specified amount of memory via mmap and return its address
181 Nasm::X86::Variable::and - And two variables
182 Nasm::X86::Variable::arithmetic - Return a variable containing the result of an arithmetic operation on the left hand and right hand side variables
183 Nasm::X86::Variable::assign - Assign to the left hand side the value of the right hand side
184 Nasm::X86::Variable::boolean - Combine the left hand variable with the right hand variable via a boolean operator
185 Nasm::X86::Variable::clearMaskBit - Clear a bit in the specified mask register retaining the other bits
186 Nasm::X86::Variable::clearMemory - Clear the memory described in this variable
187 Nasm::X86::Variable::clone - Clone a variable to create a new variable
188 Nasm::X86::Variable::copy - Copy one variable into another
189 Nasm::X86::Variable::copyAddress - Copy a reference to a variable
190 Nasm::X86::Variable::copyMemory - Copy from one block of memory to another
191 Nasm::X86::Variable::debug - Dump the value of a variable on stdout with an indication of where the dump came from
192 Nasm::X86::Variable::dec - Decrement a variable
193 Nasm::X86::Variable::divide - Divide the left hand variable by the right hand variable and return the result as a new variable
194 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
195 Nasm::X86::Variable::dump - Dump the value of a variable to the specified channel adding an optional title and new line if requested
196 Nasm::X86::Variable::eq - Check whether the left hand variable is equal to the right hand variable
197 Nasm::X86::Variable::equals - Equals operator
198 Nasm::X86::Variable::err - Dump the value of a variable on stderr
199 Nasm::X86::Variable::errNL - Dump the value of a variable on stderr and append a new line
200 Nasm::X86::Variable::for - Iterate the body limit times.
201 Nasm::X86::Variable::freeMemory - Free the memory addressed by this variable for the specified length
202 Nasm::X86::Variable::ge - Check whether the left hand variable is greater than or equal to the right hand variable
203 Nasm::X86::Variable::getBFromZmm - Get the byte from the numbered zmm register and put it in a variable
204 Nasm::X86::Variable::getConst - Load the variable from a constant in effect setting a variable to a specified value
205 Nasm::X86::Variable::getDFromZmm - Get the double word from the numbered zmm register and put it in a variable
206 Nasm::X86::Variable::getQFromZmm - Get the quad word from the numbered zmm register and put it in a variable
207 Nasm::X86::Variable::getReg - Load the variable from the named registers
208 Nasm::X86::Variable::getWFromZmm - Get the word from the numbered zmm register and put it in a variable
209 Nasm::X86::Variable::gt - Check whether the left hand variable is greater than the right hand variable
210 Nasm::X86::Variable::inc - Increment a variable
211 Nasm::X86::Variable::incDec - Increment or decrement a variable
212 Nasm::X86::Variable::isRef - Check whether the specified variable is a reference to another variable
213 Nasm::X86::Variable::le - Check whether the left hand variable is less than or equal to the right hand variable
214 Nasm::X86::Variable::loadZmm - Load bytes from the memory addressed by the specified source variable into the numbered zmm register.
215 Nasm::X86::Variable::lt - Check whether the left hand variable is less than the right hand variable
216 Nasm::X86::Variable::max - Maximum of two variables
217 Nasm::X86::Variable::min - Minimum of two variables
218 Nasm::X86::Variable::minusAssign - Implement minus and assign
219 Nasm::X86::Variable::mod - Divide the left hand variable by the right hand variable and return the remainder as a new variable
220 Nasm::X86::Variable::ne - Check whether the left hand variable is not equal to the right hand variable
221 Nasm::X86::Variable::or - Or two variables
222 Nasm::X86::Variable::out - Dump the value of a variable on stdout
223 Nasm::X86::Variable::outNL - Dump the value of a variable on stdout and append a new line
224 Nasm::X86::Variable::plusAssign - Implement plus and assign
225 Nasm::X86::Variable::pop - Pop a variable from the stack
226 Nasm::X86::Variable::printErrMemoryInHexNL - Write the memory addressed by a variable to stderr
227 Nasm::X86::Variable::printMemoryInHexNL - Write the memory addressed by a variable to stdout or stderr
228 Nasm::X86::Variable::printOutMemoryInHexNL - Write the memory addressed by a variable to stdout
229 Nasm::X86::Variable::push - Push a variable onto the stack
230 Nasm::X86::Variable::putBIntoXmm - Place the value of the content variable at the byte in the numbered xmm register
231 Nasm::X86::Variable::putBIntoZmm - Place the value of the content variable at the byte in the numbered zmm register
232 Nasm::X86::Variable::putBwdqIntoMm - Place the value of the content variable at the byte|word|double word|quad word in the numbered zmm register
233 Nasm::X86::Variable::putDIntoXmm - Place the value of the content variable at the double word in the numbered xmm register
234 Nasm::X86::Variable::putDIntoZmm - Place the value of the content variable at the double word in the numbered zmm register
235 Nasm::X86::Variable::putQIntoXmm - Place the value of the content variable at the quad word in the numbered xmm register
236 Nasm::X86::Variable::putQIntoZmm - Place the value of the content variable at the quad word in the numbered zmm register
237 Nasm::X86::Variable::putWIntoXmm - Place the value of the content variable at the word in the numbered xmm register
238 Nasm::X86::Variable::putWIntoZmm - Place the value of the content variable at the word in the numbered zmm register
239 Nasm::X86::Variable::saveZmm2222 - Save bytes into the memory addressed by the target variable from the numbered zmm register.
240 Nasm::X86::Variable::setMask - Set the mask register to ones starting at the specified position for the specified length and zeroes elsewhere
241 Nasm::X86::Variable::setMaskBit - Set a bit in the specified mask register retaining the other bits
242 Nasm::X86::Variable::setMaskFirst - Set the first bits in the specified mask register
243 Nasm::X86::Variable::setReg - Set the named registers from the content of the variable
244 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
245 Nasm::X86::Variable::str - The name of the variable
246 Nasm::X86::Variable::sub - Subtract the right hand variable from the left hand variable and return the result as a new variable
247 Nasm::X86::Variable::times - Multiply the left hand variable by the right hand variable and return the result as a new variable
248 Nasm::X86::Variable::zBroadCastD - Broadcast a double word in a variable into the numbered zmm.
249 OpenRead - Open a file, whose name is addressed by rax, for read and return the file descriptor in rax
250 OpenWrite - Create the file named by the terminated string addressed by rax for write
251 PeekR - Peek at register on stack
252 PopEax - We cannot pop a double word from the stack in 64 bit long mode using pop so we improvise
253 PopR - Pop registers from the stack
254 PopRR - Pop registers from the stack without tracking
255 PrintErrMemory - Print the memory addressed by rax for a length of rdi on stderr
256 PrintErrMemoryInHex - Dump memory from the address in rax for the length in rdi on stderr
257 PrintErrMemoryInHexNL - Dump memory from the address in rax for the length in rdi and then print a new line
258 PrintErrMemoryNL - Print the memory addressed by rax for a length of rdi followed by a new line on stderr
259 PrintErrNL - Print a new line to stderr
260 PrintErrRaxInHex - Write the content of register rax in hexadecimal in big endian notation to stderr
261 PrintErrRegisterInHex - Print the named registers as hex strings on stderr
262 PrintErrString - Print a constant string to stderr.
263 PrintErrStringNL - Print a constant string followed by a new line to stderr
264 PrintErrZF - Print the zero flag without disturbing it on stderr
265 PrintMemory - Print the memory addressed by rax for a length of rdi on the specified channel
266 PrintMemoryInHex - Dump memory from the address in rax for the length in rdi on the specified channel.
267 PrintNL - Print a new line to stdout or stderr
268 PrintOutMemory - Print the memory addressed by rax for a length of rdi on stdout
269 PrintOutMemoryInHex - Dump memory from the address in rax for the length in rdi on stdout
270 PrintOutMemoryInHexNL - Dump memory from the address in rax for the length in rdi and then print a new line
271 PrintOutMemoryNL - Print the memory addressed by rax for a length of rdi followed by a new line on stdout
272 PrintOutNL - Print a new line to stderr
273 PrintOutRaxInHex - Write the content of register rax in hexadecimal in big endian notation to stderr
274 PrintOutRaxInReverseInHex - Write the content of register rax to stderr in hexadecimal in little endian notation
275 PrintOutRegisterInHex - Print the named registers as hex strings on stdout
276 PrintOutRegistersInHex - Print the general purpose registers in hex
277 PrintOutRflagsInHex - Print the flags register in hex
278 PrintOutRipInHex - Print the instruction pointer in hex
279 PrintOutString - Print a constant string to stdout.
280 PrintOutStringNL - Print a constant string followed by a new line to stdout
281 PrintOutZF - Print the zero flag without disturbing it on stdout
282 PrintRaxInHex - Write the content of register rax in hexadecimal in big endian notation to the specified channel
283 PrintRegisterInHex - Print the named registers as hex strings
284 PrintString - Print a constant string to the specified channel
285 PrintUtf32 - Print the specified number of utf32 characters at the specified address
286 PushR - Push registers onto the stack
287 PushRR - Push registers onto the stack without tracking
288 Rb - Layout bytes in the data segment and return their label
289 Rbwdq - Layout data
290 RComment - Insert a comment into the read only data segment
291 Rd - Layout double words in the data segment and return their label
292 ReadFile - Read a file whose name is addressed by rax into memory.
293 ReadTimeStampCounter - Read the time stamp counter and return the time in nanoseconds in rax
294 RegisterSize - Return the size of a register
295 removeNonAsciiChars - Return a copy of the specified string with all the non ascii characters removed
296 ReorderSyscallRegisters - Map the list of registers provided to the 64 bit system call sequence
297 RestoreFirstFour - Restore the first 4 parameter registers
298 RestoreFirstFourExceptRax - Restore the first 4 parameter registers except rax so it can return its value
299 RestoreFirstFourExceptRaxAndRdi - Restore the first 4 parameter registers except rax and rdi so we can return a pair of values
300 RestoreFirstSeven - Restore the first 7 parameter registers
301 RestoreFirstSevenExceptRax - Restore the first 7 parameter registers except rax which is being used to return the result
302 RestoreFirstSevenExceptRaxAndRdi - Restore the first 7 parameter registers except rax and rdi which are being used to return the results
303 Rq - Layout quad words in the data segment and return their label
304 Rs - Layout bytes in read only memory and return their label
305 Rutf8 - Layout a utf8 encoded string as bytes in read only memory and return their label
306 Rw - Layout words in the data segment and return their label
307 SaveFirstFour - Save the first 4 parameter registers making any parameter registers read only
308 SaveFirstSeven - Save the first 7 parameter registers
309 Scope - Create and stack a new scope and continue with it as the current scope
310 ScopeEnd - End the current scope and continue with the containing parent scope
311 SetLabel - Set a label in the code section
312 SetLengthOfShortString - Set the length of the short string held in the numbered zmm register into the specified register
313 SetMaskRegister - Set the mask register to ones starting at the specified position for the specified length and zeroes elsewhere
314 SetZF - Set the zero flag
315 Start - Initialize the assembler
316 StatSize - Stat a file whose name is addressed by rax to get its size in rax
317 StringLength - Length of a zero terminated string
318 Structure - Create a structure addressed by a register
319 Subroutine - Create a subroutine that can be called in assembler code
320 Then - Then body for an If statement
321 totalBytesAssembled - Total size in bytes of all files assembled during testing
322 Trace - Add tracing code
323 unlinkFile - Unlink the named file
324 UnReorderSyscallRegisters - Recover the initial values in registers that were reordered
325 Variable - Create a new variable with the specified size and name initialized via an expression
326 Vb - Define a byte variable
327 Vd - Define a double word variable
328 Vq - Define a quad variable
329 Vr - Define a reference variable
330 Vw - Define a word variable
331 Vx - Define an xmm variable
332 VxyzInit - Initialize an xyz register from general purpose registers
333 Vy - Define an ymm variable
334 Vz - Define an zmm variable
335 WaitPid - Wait for the pid in rax to complete
336 xmm - Add xmm to the front of a list of register expressions
337 ymm - Add ymm to the front of a list of register expressions
338 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.