Looking for help!
Name
Nasm::X86 - Generate Nasm assembler code
Synopsis
Write and execute x64 instructions using perl as a macro assembler as shown in the following examples.
Avx512 instructions
Use avx512 instructions to reorder data using 512 bit zmm* registers:
Start;
my $q = Rs my $s = join '', ('a'..'p')x4;
Mov rax, Ds('0'x128);
Vmovdqu32 zmm0, "[$q]";
Vprolq zmm1, zmm0, 32;
Vmovdqu32 "[rax]", zmm1;
Mov rdi, length $s;
PrintOutMemory;
Exit;
ok $s =~ m(abcdefghijklmnopabcdefghijklmnopabcdefghijklmnopabcdefghijklmnop)s;
ok Assemble =~ m(efghabcdmnopijklefghabcdmnopijklefghabcdmnopijklefghabcdmnopijkl)s;
Dynamic string held in an arena
Create a dynamic byte string, add some content to it, write the byte string to a file and then execute it:.
Start;
my $s = CreateByteString; # Create a string
$s->ql(<<END); # Write code to execute
#!/usr/bin/bash
whoami
ls -la
pwd
END
$s->write; # Write code to a temporary file
$s->bash; # Execute the temporary file
$s->unlink; # Execute the temporary file
Exit; # Return to operating system
my $u = qx(whoami); chomp($u);
ok Assemble =~ m($u);
Process management
Start a child process and wait for it, printing out the process identifiers of each process involved:
Start; # Start the program
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;
};
Exit; # Return to operating system
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:
Start; # Start the program
Mov rax, Rs($0); # File to read
ReadFile; # Read file
PrintOutMemory; # Print memory
Exit; # Return to operating system
my $r = Assemble; # Assemble and execute
ok index($r, readFile($0)) > -1; # Output contains this file
Installation
You will need the Intel Software Development Emulator and the Networkwide Assembler installed on your test system. For full details of how to do this see: https://github.com/philiprbrenan/NasmX86/blob/main/.github/workflows/main.yml
Description
Generate Nasm assembler code
Version "20210419".
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:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Exit;
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:
Start;
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;
Exit;
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:
Start;
Comment "Print a string from memory";
my $s = "Hello World";
Mov rax, Rs($s); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rdi, length $s;
PrintOutMemory;
Exit;
ok Assemble =~ m(Hello World);
Start;
my $q = Rs('abababab'); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov(rax, 1);
Mov(rbx, 2);
Mov(rcx, 3);
Mov(rdx, 4);
Mov(r8, 5);
Lea r9, "[rax+rbx]";
PrintOutRegistersInHex;
Exit;
my $r = Assemble;
ok $r =~ m( r8: 0000 0000 0000 0005.* r9: 0000 0000 0000 0003.*rax: 0000 0000 0000 0001)s;
ok $r =~ m(rbx: 0000 0000 0000 0002.*rcx: 0000 0000 0000 0003.*rdx: 0000 0000 0000 0004)s;
Db(@bytes)
Layout bytes in the data segment and return their label
Parameter Description
1 @bytes Bytes to layout
Dw(@words)
Layout words in the data segment and return their label
Parameter Description
1 @words Words to layout
Dd(@dwords)
Layout double words in the data segment and return their label
Parameter Description
1 @dwords Double words to layout
Dq(@qwords)
Layout quad words in the data segment and return their label
Parameter Description
1 @qwords Quad words to layout
Rb(@bytes)
Layout bytes in the data segment and return their label
Parameter Description
1 @bytes Bytes to layout
Rw(@words)
Layout words in the data segment and return their label
Parameter Description
1 @words Words to layout
Rd(@dwords)
Layout double words in the data segment and return their label
Parameter Description
1 @dwords Double words to layout
Rq(@qwords)
Layout quad words in the data segment and return their label
Parameter Description
1 @qwords Quad words to layout
Registers
Operations on registers
SaveFirstFour()
Save the first 4 parameter registers
Example:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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:
Start;
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 fof syscall # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rdi;
UnReorderSyscallRegisters r8,r9; # Unreorder the registers to recover their original values
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rdi;
Exit; # Return to operating system
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:
Start;
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 fof syscall
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rdi;
UnReorderSyscallRegisters r8,r9; # Unreorder the registers to recover their original values # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rdi;
Exit; # Return to operating system
ok Assemble =~ m(rax:.*08.*rdi:.*9.*rax:.*1.*rdi:.*2.*)s;
ReorderXmmRegisters(@registers) = map {"xmm$_"} @_;)
Map the list of xmm registers provided to 0-31
Parameter Description
1 @registers) = map {"xmm$_"} @_; Registers
Example:
Start;
my $t = GenTree(2,2); # Tree description
$t->node->&*; # Root
Movdqa xmm1, xmm0;
if (1) # New left node
{$t->node->&*; # Node in xmm0
Movdqa xmm2, xmm0; # Left is in xmm2
ReorderXmmRegisters my @x = (1,0); # Insert left under root # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$t->insertLeft->&*;
UnReorderXmmRegisters @x;
$t->dump->("Left"); # Left node after insertion
}
if (1) # New right node in xmm0
{$t->node->&*;
Movdqa xmm3, xmm0; # Right is in xmm3
ReorderXmmRegisters my @x = (1,0); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$t->insertRight->&*;
UnReorderXmmRegisters @x;
$t->dump->("Right"); # Right node after insertion
}
Movdqa xmm0, xmm1;
$t->dump->("Root"); # Root node after insertions
$t->isRoot->&*;
If {PrintOutStringNL "root"} sub {PrintOutStringNL "NOT root"};
PushR xmm0; # Dump underlying byte string
PopR rdi, rax;
$t->byteString->dump;
Exit; # Return to operating system
is_deeply Assemble, <<END; # Test tree so produced
Left
ArenaTreeNode at: 0000 0000 0000 00B0
up: 0000 0000 0000 0010
left: 0000 0000 0000 0000
right: 0000 0000 0000 0000
Right
ArenaTreeNode at: 0000 0000 0000 0150
up: 0000 0000 0000 0010
left: 0000 0000 0000 0000
right: 0000 0000 0000 0000
Root
ArenaTreeNode at: 0000 0000 0000 0010
up: 0000 0000 0000 0000
left: 0000 0000 0000 00B0
right: 0000 0000 0000 0150
root
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 01E0
END
UnReorderXmmRegisters(@registers)
Recover the initial values in the xmm registers that were reordered
Parameter Description
1 @registers Registers
Example:
Start;
my $t = GenTree(2,2); # Tree description
$t->node->&*; # Root
Movdqa xmm1, xmm0;
if (1) # New left node
{$t->node->&*; # Node in xmm0
Movdqa xmm2, xmm0; # Left is in xmm2
ReorderXmmRegisters my @x = (1,0); # Insert left under root
$t->insertLeft->&*;
UnReorderXmmRegisters @x; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$t->dump->("Left"); # Left node after insertion
}
if (1) # New right node in xmm0
{$t->node->&*;
Movdqa xmm3, xmm0; # Right is in xmm3
ReorderXmmRegisters my @x = (1,0);
$t->insertRight->&*;
UnReorderXmmRegisters @x; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$t->dump->("Right"); # Right node after insertion
}
Movdqa xmm0, xmm1;
$t->dump->("Root"); # Root node after insertions
$t->isRoot->&*;
If {PrintOutStringNL "root"} sub {PrintOutStringNL "NOT root"};
PushR xmm0; # Dump underlying byte string
PopR rdi, rax;
$t->byteString->dump;
Exit; # Return to operating system
is_deeply Assemble, <<END; # Test tree so produced
Left
ArenaTreeNode at: 0000 0000 0000 00B0
up: 0000 0000 0000 0010
left: 0000 0000 0000 0000
right: 0000 0000 0000 0000
Right
ArenaTreeNode at: 0000 0000 0000 0150
up: 0000 0000 0000 0010
left: 0000 0000 0000 0000
right: 0000 0000 0000 0000
Root
ArenaTreeNode at: 0000 0000 0000 0010
up: 0000 0000 0000 0000
left: 0000 0000 0000 00B0
right: 0000 0000 0000 0150
root
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 01E0
END
RegisterSize($r)
Return the size of a register
Parameter Description
1 $r Register
Example:
Start;
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;
ReverseBytesInRax;
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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:
Start;
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;
Exit;
ok Assemble =~ m(k0: 0000 0000 0000 0008.*k1: 0000 0000 0000 0000)s;
SetRegisterToMinusOne($register)
Set the specified register to -1
Parameter Description
1 $register Register to set
Example:
Start;
SetRegisterToMinusOne rax; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
Exit; # Return to operating system
ok Assemble =~ m(rax: FFFF FFFF FFFF FFFF);
SetZF()
Set the zero flag
Example:
Start;
SetZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
ClearZF;
PrintOutZF;
SetZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
SetZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
ClearZF;
PrintOutZF;
Exit; # Return to operating system
ok Assemble =~ m(ZF=1.*ZF=0.*ZF=1.*ZF=1.*ZF=0)s;
ClearZF()
Set the zero flag
Example:
Start;
SetZF;
PrintOutZF;
ClearZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
SetZF;
PrintOutZF;
SetZF;
PrintOutZF;
ClearZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutZF;
Exit; # Return to operating system
ok Assemble =~ m(ZF=1.*ZF=0.*ZF=1.*ZF=1.*ZF=0)s;
Structured Programming
Structured programming constructs
If($then, $else)
If
Parameter Description
1 $then Then - required
2 $else Else - optional
Example:
Start;
Mov rax, 0;
Test rax,rax;
If # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
{PrintOutRegisterInHex rax;
} sub
{PrintOutRegisterInHex rbx;
};
Mov rax, 1;
Test rax,rax;
If # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
{PrintOutRegisterInHex rcx;
} sub
{PrintOutRegisterInHex rdx;
};
Exit;
ok Assemble =~ m(rbx.*rcx)s;
For($body, $register, $limit, $increment)
For
Parameter Description
1 $body Body
2 $register Register
3 $limit Limit on loop
4 $increment Increment
Example:
Start; # Start the program
For # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
{PrintOutRegisterInHex rax
} rax, 16, 1;
Exit; # Return to operating system
my $r = Assemble;
ok $r =~ m(( 0000){3} 0000)i;
ok $r =~ m(( 0000){3} 000F)i;
S($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.
Example:
Start;
Mov rax, 0x44332211;
PrintOutRegisterInHex rax;
my $s = S # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
{PrintOutRegisterInHex rax;
Inc rax;
PrintOutRegisterInHex rax;
};
Call $s;
PrintOutRegisterInHex rax;
Exit;
my $r = Assemble;
ok $r =~ m(0000 0000 4433 2211.*2211.*2212.*0000 0000 4433 2212)s;
Comment(@comment)
Insert a comment into the assembly code
Parameter Description
1 @comment Text of comment
Example:
Start;
Comment "Print a string from memory"; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $s = "Hello World";
Mov rax, Rs($s);
Mov rdi, length $s;
PrintOutMemory;
Exit;
ok Assemble =~ m(Hello World);
PrintOutNL()
Print a new line to stdout
Example:
Start;
my $q = Rs('abababab');
Mov(rax, "[$q]");
PrintOutString "rax: ";
PrintOutRaxInHex;
PrintOutNL; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Xor rax, rax;
PrintOutString "rax: ";
PrintOutRaxInHex;
PrintOutNL; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Exit;
ok Assemble =~ m(rax: 6261 6261 6261 6261.*rax: 0000 0000 0000 0000)s;
PrintOutString($string)
Print a constant string to sysout.
Parameter Description
1 $string String
Example:
Start;
PrintOutString "Hello World"; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Exit;
ok Assemble =~ m(Hello World);
PrintOutStringNL($string)
Print a constant string to sysout followed by new line
Parameter Description
1 $string String
Example:
Start;
my $t = GenTree(2,2); # Tree description
$t->node->&*; # Root
Movdqa xmm1, xmm0;
if (1) # New left node
{$t->node->&*; # Node in xmm0
Movdqa xmm2, xmm0; # Left is in xmm2
ReorderXmmRegisters my @x = (1,0); # Insert left under root
$t->insertLeft->&*;
UnReorderXmmRegisters @x;
$t->dump->("Left"); # Left node after insertion
}
if (1) # New right node in xmm0
{$t->node->&*;
Movdqa xmm3, xmm0; # Right is in xmm3
ReorderXmmRegisters my @x = (1,0);
$t->insertRight->&*;
UnReorderXmmRegisters @x;
$t->dump->("Right"); # Right node after insertion
}
Movdqa xmm0, xmm1;
$t->dump->("Root"); # Root node after insertions
$t->isRoot->&*;
If {PrintOutStringNL "root"} sub {PrintOutStringNL "NOT root"}; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PushR xmm0; # Dump underlying byte string
PopR rdi, rax;
$t->byteString->dump;
Exit; # Return to operating system
is_deeply Assemble, <<END; # Test tree so produced
Left
ArenaTreeNode at: 0000 0000 0000 00B0
up: 0000 0000 0000 0010
left: 0000 0000 0000 0000
right: 0000 0000 0000 0000
Right
ArenaTreeNode at: 0000 0000 0000 0150
up: 0000 0000 0000 0010
left: 0000 0000 0000 0000
right: 0000 0000 0000 0000
Root
ArenaTreeNode at: 0000 0000 0000 0010
up: 0000 0000 0000 0000
left: 0000 0000 0000 00B0
right: 0000 0000 0000 0150
root
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 01E0
END
PrintOutRaxInHex()
Write the content of register rax to stderr in hexadecimal in big endian notation
Example:
Start;
my $q = Rs('abababab');
Mov(rax, "[$q]");
PrintOutString "rax: ";
PrintOutRaxInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
Xor rax, rax;
PrintOutString "rax: ";
PrintOutRaxInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
Exit;
ok Assemble =~ m(rax: 6261 6261 6261 6261.*rax: 0000 0000 0000 0000)s;
ReverseBytesInRax()
Reverse the bytes in rax
Example:
Start;
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;
ReverseBytesInRax; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
my $l = Label;
Jmp $l;
SetLabel $l;
Exit;
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;
PrintOutRaxInReverseInHex()
Write the content of register rax to stderr in hexadecimal in little endian notation
Example:
Start;
Mov rax, 0x07654321;
Shl rax, 32;
Or rax, 0x07654321;
PrintOutRaxInHex;
PrintOutNL;
PrintOutRaxInReverseInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
Push rax;
Mov rax, rsp;
Mov rdi, 8;
PrintOutMemoryInHex;
PrintOutNL;
Mov rax, 4096;
Push rax;
Mov rax, rsp;
Mov rdi, 8;
PrintOutMemoryInHex;
PrintOutNL;
Exit;
is_deeply Assemble, <<END;
0765 4321 0765 4321
2143 6507 2143 6507
0765 4321 0765 4321
0010 0000 0000 0000
END
PrintOutRegisterInHex(@r)
Print any register as a hex string
Parameter Description
1 @r Name of the register to print
Example:
Start;
my $q = Rs(('a'..'p')x4);
Mov r8,"[$q]";
PrintOutRegisterInHex r8; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Exit;
ok Assemble =~ m(r8: 6867 6665 6463 6261)s;
PrintOutRegistersInHex()
Print the general purpose registers in hex
Example:
Start;
my $q = Rs('abababab');
Mov(rax, 1);
Mov(rbx, 2);
Mov(rcx, 3);
Mov(rdx, 4);
Mov(r8, 5);
Lea r9, "[rax+rbx]";
PrintOutRegistersInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Exit;
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;
PrintOutZF()
Print the zero flag without disturbing it
Example:
Start;
SetZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ClearZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
SetZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
SetZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ClearZF;
PrintOutZF; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Exit; # Return to operating system
ok Assemble =~ m(ZF=1.*ZF=0.*ZF=1.*ZF=1.*ZF=0)s;
Processes
Create and manage processes
Fork()
Fork
Example:
Start; # Start the program
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;
};
Exit; # Return to operating system
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:
Start; # Start the program
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;
};
Exit; # Return to operating system
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:
Start;
GetPidInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
Exit; # Return to operating system
ok Assemble =~ m(rax: 00);
GetPPid()
Get parent process identifier
Example:
Start; # Start the program
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;
};
Exit; # Return to operating system
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:
Start; # Start the program
GetUid; # Userid # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
Exit; # Return to operating system
my $r = Assemble;
ok $r =~ m(rax:( 0000){3});
WaitPid()
Wait for the pid in rax to complete
Example:
Start; # Start the program
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;
};
Exit; # Return to operating system
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:
Start;
for(1..10)
{ReadTimeStampCounter; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
}
Exit;
my @s = split /
/, Assemble;
my @S = sort @s;
is_deeply \@s, \@S;
Stack
Manage data on the stack
Push, Pop, Peek
Generic versions of push, pop, peek
PushR(@r)
Push registers onto the stack
Parameter Description
1 @r Register
Example:
Start;
Mov rax, 0x11111111;
Mov rbx, 0x22222222;
PushR rax; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Mov rax, 0x33333333;
PeekR rbx;
PopR rax;
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
Exit;
ok Assemble =~ m(rax: 0000 0000 1111 1111.*rbx: 0000 0000 1111 1111)s;
PopR(@r)
Pop registers from the stack
Parameter Description
1 @r Register
Example:
Start;
Mov rax, 0x11111111;
Mov rbx, 0x22222222;
PushR rax;
Mov rax, 0x33333333;
PeekR rbx;
PopR rax; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
Exit;
ok Assemble =~ m(rax: 0000 0000 1111 1111.*rbx: 0000 0000 1111 1111)s;
PeekR($r)
Peek at register on stack
Parameter Description
1 $r Register
Example:
Start;
Mov rax, 0x11111111;
Mov rbx, 0x22222222;
PushR rax;
Mov rax, 0x33333333;
PeekR rbx; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PopR rax;
PrintOutRegisterInHex rax;
PrintOutRegisterInHex rbx;
Exit;
ok Assemble =~ m(rax: 0000 0000 1111 1111.*rbx: 0000 0000 1111 1111)s;
Declarations
Declare variables and structures
Structures
Declare a structure
Structure($register)
Create a structure addressed by a register
Parameter Description
1 $register Register locating the structure
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
StructureField::addr($field)
Address a field in a structure
Parameter Description
1 $field Field
All8Structure($base, $N)
Create a structure consisting of 8 byte fields
Parameter Description
1 $base Base register
2 $N Number of variables required
Stack Frame
Declare local variables in a frame on the stack
LocalData()
Map local data
LocalData::start($local)
Start a local data area on the stack
Parameter Description
1 $local Local data descriptor
LocalData::free($local)
Free a local data area on the stack
Parameter Description
1 $local Local data descriptor
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
LocalVariable::stack($variable)
Address a local variable on the stack
Parameter Description
1 $variable Variable
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
Memory
Allocate and print memory
PrintOutMemoryInHex()
Dump memory from the address in rax for the length in rdi
Example:
Start;
Mov rax, 0x07654321;
Shl rax, 32;
Or rax, 0x07654321;
PrintOutRaxInHex;
PrintOutNL;
PrintOutRaxInReverseInHex;
PrintOutNL;
Push rax;
Mov rax, rsp;
Mov rdi, 8;
PrintOutMemoryInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
Mov rax, 4096;
Push rax;
Mov rax, rsp;
Mov rdi, 8;
PrintOutMemoryInHex; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutNL;
Exit;
is_deeply Assemble, <<END;
0765 4321 0765 4321
2143 6507 2143 6507
0765 4321 0765 4321
0010 0000 0000 0000
END
PrintOutMemory()
Print the memory addressed by rax for a length of rdi
Example:
Start;
Comment "Print a string from memory";
my $s = "Hello World";
Mov rax, Rs($s);
Mov rdi, length $s;
PrintOutMemory; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Exit;
ok Assemble =~ m(Hello World);
AllocateMemory()
Allocate the amount of memory specified in rax via mmap and return the address of the allocated memory in rax
Example:
Start;
my $N = 2048;
my $q = Rs('a'..'p');
Mov rax, $N;
AllocateMemory; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
Vmovdqu8 xmm0, "[$q]";
Vmovdqu8 "[rax]", xmm0;
Mov rdi,16;
PrintOutMemory;
PrintOutNL;
Mov rdi, $N;
FreeMemory;
PrintOutRegisterInHex rax;
Exit;
ok Assemble =~ m(abcdefghijklmnop)s;
Start;
my $N = 4096;
my $S = RegisterSize rax;
Mov rax, $N;
AllocateMemory; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
Mov rdi, $N;
ClearMemory;
PrintOutRegisterInHex rax;
PrintOutMemoryInHex;
Exit;
my $r = Assemble;
if ($r =~ m((0000.*0000))s)
{is_deeply length($1), 9776;
}
FreeMemory()
Free memory via mmap. The address of the memory is in rax, the length to free is in rdi
Example:
Start;
my $N = 2048;
my $q = Rs('a'..'p');
Mov rax, $N;
AllocateMemory;
PrintOutRegisterInHex rax;
Vmovdqu8 xmm0, "[$q]";
Vmovdqu8 "[rax]", xmm0;
Mov rdi,16;
PrintOutMemory;
PrintOutNL;
Mov rdi, $N;
FreeMemory; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
Exit;
ok Assemble =~ m(abcdefghijklmnop)s;
Start;
my $N = 4096;
my $S = RegisterSize rax;
Mov rax, $N;
AllocateMemory;
PrintOutRegisterInHex rax;
Mov rdi, $N;
ClearMemory;
PrintOutRegisterInHex rax;
PrintOutMemoryInHex;
Exit;
my $r = Assemble;
if ($r =~ m((0000.*0000))s)
{is_deeply length($1), 9776;
}
ClearMemory()
Clear memory - the address of the memory is in rax, the length in rdi
Example:
Start;
my $N = 4096;
my $S = RegisterSize rax;
Mov rax, $N;
AllocateMemory;
PrintOutRegisterInHex rax;
Mov rdi, $N;
ClearMemory; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
PrintOutMemoryInHex;
Exit;
my $r = Assemble;
if ($r =~ m((0000.*0000))s)
{is_deeply length($1), 9776;
}
CopyMemory()
Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
Files
Process a file
OpenRead()
Open a file, whose name is addressed by rax, for read and return the file descriptor in rax
Example:
Start; # Start the program
Mov rax, Rs($0); # File to read
OpenRead; # Open file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
CloseFile; # Close file
PrintOutRegisterInHex rax;
Mov rax, Rs(my $f = "zzz.txt"); # File to write
OpenWrite; # Open file
CloseFile; # Close file
Exit; # Return to operating system
my $r = Assemble;
ok $r =~ m(( 0000){3} 0003)i; # Expected file number
ok $r =~ m(( 0000){4})i; # Expected file number
ok -e $f; # Created file
unlink $f;
OpenWrite()
Create the file named by the terminated string addressed by rax for write
Example:
Start; # Start the program
Mov rax, Rs($0); # File to read
OpenRead; # Open file
PrintOutRegisterInHex rax;
CloseFile; # Close file
PrintOutRegisterInHex rax;
Mov rax, Rs(my $f = "zzz.txt"); # File to write
OpenWrite; # Open file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
CloseFile; # Close file
Exit; # Return to operating system
my $r = Assemble;
ok $r =~ m(( 0000){3} 0003)i; # Expected file number
ok $r =~ m(( 0000){4})i; # Expected file number
ok -e $f; # Created file
unlink $f;
CloseFile()
Close the file whose descriptor is in rax
Example:
Start; # Start the program
Mov rax, Rs($0); # File to read
OpenRead; # Open file
PrintOutRegisterInHex rax;
CloseFile; # Close file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
Mov rax, Rs(my $f = "zzz.txt"); # File to write
OpenWrite; # Open file
CloseFile; # Close file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
Exit; # Return to operating system
my $r = Assemble;
ok $r =~ m(( 0000){3} 0003)i; # Expected file number
ok $r =~ m(( 0000){4})i; # Expected file number
ok -e $f; # Created file
unlink $f;
StatSize()
Stat a file whose name is addressed by rax to get its size in rax
Example:
Start; # Start the program
Mov rax, Rs($0); # File to stat
StatSize; # Stat the file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutRegisterInHex rax;
Exit; # Return to operating system
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()
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
Example:
Start; # Start the program
Mov rax, Rs($0); # File to read
ReadFile; # Read file # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutMemory; # Print memory
Exit; # Return to operating system
my $r = Assemble; # Assemble and execute
ok index(removeNonAsciiChars($r), removeNonAsciiChars(readFile $0)) >= 0; # Output contains this file
Strings
Operations on Strings
CreateByteString()
Create an relocatable string of bytes in an arena and returns its address in rax
Example:
Start; # Start the program
my $s = CreateByteString; # Create a string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$s->q(my $t = 'ab'); # Append a constant to the byte string
$s->nl; # New line
Mov rdi, rax; # Save source byte string
CreateByteString; # Create target byte string # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$s->copy; # Copy source to target
Xchg rdi, rax; # Swap source and target byte strings
$s->copy; # Copy source to target
Xchg rdi, rax; # Swap source and target byte strings
$s->copy;
Xchg rdi, rax;
$s->copy;
Xchg rdi, rax;
$s->copy;
$s->out; # Print byte string
$s->clear; # Clear byte string
Exit; # Return to operating system
my $T = "$t
" x 8; # Expected response
ok Assemble =~ m($T)s; # Assemble and execute
ByteString::makeReadOnly($byteString)
Make a byte string read only
Parameter Description
1 $byteString Byte string descriptor
ByteString::makeWritable($byteString)
Make a byte string writable
Parameter Description
1 $byteString Byte string descriptor
ByteString::allocate($byteString)
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
ByteString::m($byteString)
Append the content with length rdi addressed by rsi to the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
ByteString::q($byteString, $const)
Append a quoted string == a constant to the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
2 $const Constant
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 descriptor
2 $const Constant
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 Decimal number of character to be appended
ByteString::nl($byteString)
Append a new line to the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
ByteString::z($byteString)
Append a trailing zero to the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
ByteString::rdiInHex()
Add the content of register rdi in hexadecimal in big endian notation to a byte string
ByteString::copy($byteString)
Append the byte string addressed by rdi to the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
ByteString::clear($byteString)
Clear the byte string addressed by rax
Parameter Description
1 $byteString Byte string descriptor
ByteString::write($byteString)
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
ByteString::read($byteString)
Read the file named in the byte string (terminated with a zero byte) addressed by rax and place it into the byte string after clearing the byte string to remove the file name contained therein.
Parameter Description
1 $byteString Byte string descriptor
ByteString::out($byteString)
Print the specified byte string addressed by rax on sysout
Parameter Description
1 $byteString Byte string descriptor
ByteString::bash($byteString)
Execute the file named in the byte string addressed by rax with bash
Parameter Description
1 $byteString Byte string descriptor
ByteString::unlink($byteString)
Unlink the file named in the byte string addressed by rax with bash
Parameter Description
1 $byteString Byte string descriptor
ByteString::dump($byteString)
Dump details of a byte string
Parameter Description
1 $byteString Byte string descriptor
GenTree($keyLength, $dataLength)
Generate a set of routines to manage a tree held in a byte string with key and data fields of specified widths. Allocate a byte string to contain the tree, return its address in xmm0=(0, tree).
Parameter Description
1 $keyLength Fixed key length in bytes
2 $dataLength Fixed data length in bytes
Example:
Start;
my $t = GenTree(2,2); # Tree description # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$t->node->&*; # Root
Movdqa xmm1, xmm0;
if (1) # New left node
{$t->node->&*; # Node in xmm0
Movdqa xmm2, xmm0; # Left is in xmm2
ReorderXmmRegisters my @x = (1,0); # Insert left under root
$t->insertLeft->&*;
UnReorderXmmRegisters @x;
$t->dump->("Left"); # Left node after insertion
}
if (1) # New right node in xmm0
{$t->node->&*;
Movdqa xmm3, xmm0; # Right is in xmm3
ReorderXmmRegisters my @x = (1,0);
$t->insertRight->&*;
UnReorderXmmRegisters @x;
$t->dump->("Right"); # Right node after insertion
}
Movdqa xmm0, xmm1;
$t->dump->("Root"); # Root node after insertions
$t->isRoot->&*;
If {PrintOutStringNL "root"} sub {PrintOutStringNL "NOT root"};
PushR xmm0; # Dump underlying byte string
PopR rdi, rax;
$t->byteString->dump;
Exit; # Return to operating system
is_deeply Assemble, <<END; # Test tree so produced
Left
ArenaTreeNode at: 0000 0000 0000 00B0
up: 0000 0000 0000 0010
left: 0000 0000 0000 0000
right: 0000 0000 0000 0000
Right
ArenaTreeNode at: 0000 0000 0000 0150
up: 0000 0000 0000 0010
left: 0000 0000 0000 0000
right: 0000 0000 0000 0000
Root
ArenaTreeNode at: 0000 0000 0000 0010
up: 0000 0000 0000 0000
left: 0000 0000 0000 00B0
right: 0000 0000 0000 0150
root
Byte String
Size: 0000 0000 0000 1000
Used: 0000 0000 0000 01E0
END
Assemble
Assemble generated code
Start()
Initialize the assembler
Example:
Start; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
PrintOutString "Hello World";
Exit;
ok Assemble =~ m(Hello World);
Exit($c)
Exit with the specified return code or zero if no return code supplied
Parameter Description
1 $c Return code
Example:
Start;
PrintOutString "Hello World";
Exit; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
ok Assemble =~ m(Hello World);
Assemble(%options)
Assemble the generated code
Parameter Description
1 %options Options
Example:
Start;
PrintOutString "Hello World";
Exit;
ok Assemble =~ m(Hello World); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
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
ByteString::updateSpace($byteString)
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
removeNonAsciiChars($string)
Return a copy of the specified string with all the non ascii characters removed
Parameter Description
1 $string String
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 amount of memory specified in rax via mmap and return the address of the allocated memory in rax
4 Assemble - Assemble the generated code
5 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
6 ByteString::bash - Execute the file named in the byte string addressed by rax with bash
7 ByteString::char - Append a character expressed as a decimal number to the byte string addressed by rax
8 ByteString::clear - Clear the byte string addressed by rax
9 ByteString::copy - Append the byte string addressed by rdi to the byte string addressed by rax
10 ByteString::dump - Dump details of a byte string
11 ByteString::m - Append the content with length rdi addressed by rsi to the byte string addressed by rax
12 ByteString::makeReadOnly - Make a byte string read only
13 ByteString::makeWritable - Make a byte string writable
14 ByteString::nl - Append a new line to the byte string addressed by rax
15 ByteString::out - Print the specified byte string addressed by rax on sysout
16 ByteString::q - Append a quoted string == a constant to the byte string addressed by rax
17 ByteString::ql - Append a quoted string containing new line characters to the byte string addressed by rax
18 ByteString::rdiInHex - Add the content of register rdi in hexadecimal in big endian notation to a byte string
19 ByteString::read - Read the file named in the byte string (terminated with a zero byte) addressed by rax and place it into the byte string after clearing the byte string to remove the file name contained therein.
20 ByteString::unlink - Unlink the file named in the byte string addressed by rax with bash
21 ByteString::updateSpace - Make sure that the byte string addressed by rax has enough space to accommodate content of length rdi
22 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
23 ByteString::z - Append a trailing zero to the byte string addressed by rax
24 ClearMemory - Clear memory - the address of the memory is in rax, the length in rdi
25 ClearRegisters - Clear registers by setting them to zero
26 ClearZF - Set the zero flag
27 CloseFile - Close the file whose descriptor is in rax
28 Comment - Insert a comment into the assembly code
29 CopyMemory - Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
30 CreateByteString - Create an relocatable string of bytes in an arena and returns its address in rax
31 Db - Layout bytes in the data segment and return their label
32 Dbwdq - Layout data
33 Dd - Layout double words in the data segment and return their label
34 Dq - Layout quad words in the data segment and return their label
35 Ds - Layout bytes in memory and return their label
36 Dw - Layout words in the data segment and return their label
37 Exit - Exit with the specified return code or zero if no return code supplied
38 For - For
39 Fork - Fork
40 FreeMemory - Free memory via mmap.
41 GenTree - Generate a set of routines to manage a tree held in a byte string with key and data fields of specified widths.
42 GetPid - Get process identifier
43 GetPidInHex - Get process identifier in hex as 8 zero terminated bytes in rax
44 GetPPid - Get parent process identifier
45 GetUid - Get userid of current process
46 hexTranslateTable - Create/address a hex translate table and return its label
47 If - If
48 Label - Create a unique label
49 LocalData - Map local data
50 LocalData::allocate8 - Add some 8 byte local variables and return an array of variable definitions
51 LocalData::free - Free a local data area on the stack
52 LocalData::start - Start a local data area on the stack
53 LocalData::variable - Add a local variable
54 LocalVariable::stack - Address a local variable on the stack
55 OpenRead - Open a file, whose name is addressed by rax, for read and return the file descriptor in rax
56 OpenWrite - Create the file named by the terminated string addressed by rax for write
57 PeekR - Peek at register on stack
58 PopR - Pop registers from the stack
59 PrintOutMemory - Print the memory addressed by rax for a length of rdi
60 PrintOutMemoryInHex - Dump memory from the address in rax for the length in rdi
61 PrintOutNL - Print a new line to stdout
62 PrintOutRaxInHex - Write the content of register rax to stderr in hexadecimal in big endian notation
63 PrintOutRaxInReverseInHex - Write the content of register rax to stderr in hexadecimal in little endian notation
64 PrintOutRegisterInHex - Print any register as a hex string
65 PrintOutRegistersInHex - Print the general purpose registers in hex
66 PrintOutRflagsInHex - Print the flags register in hex
67 PrintOutRipInHex - Print the instruction pointer in hex
68 PrintOutString - Print a constant string to sysout.
69 PrintOutStringNL - Print a constant string to sysout followed by new line
70 PrintOutZF - Print the zero flag without disturbing it
71 PushR - Push registers onto the stack
72 Rb - Layout bytes in the data segment and return their label
73 Rbwdq - Layout data
74 Rd - Layout double words in the data segment and return their label
75 ReadFile - Read a file whose name is addressed by rax into memory.
76 ReadTimeStampCounter - Read the time stamp counter and return the time in nanoseconds in rax
77 RegisterSize - Return the size of a register
78 removeNonAsciiChars - Return a copy of the specified string with all the non ascii characters removed
79 ReorderSyscallRegisters - Map the list of registers provided to the 64 bit system call sequence
80 ReorderXmmRegisters - Map the list of xmm registers provided to 0-31
81 RestoreFirstFour - Restore the first 4 parameter registers
82 RestoreFirstFourExceptRax - Restore the first 4 parameter registers except rax so it can return its value
83 RestoreFirstFourExceptRaxAndRdi - Restore the first 4 parameter registers except rax and rdi so we can return a pair of values
84 RestoreFirstSeven - Restore the first 7 parameter registers
85 RestoreFirstSevenExceptRax - Restore the first 7 parameter registers except rax which is being used to return the result
86 RestoreFirstSevenExceptRaxAndRdi - Restore the first 7 parameter registers except rax and rdi which are being used to return the results
87 ReverseBytesInRax - Reverse the bytes in rax
88 Rq - Layout quad words in the data segment and return their label
89 Rs - Layout bytes in read only memory and return their label
90 Rw - Layout words in the data segment and return their label
91 S - 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
92 SaveFirstFour - Save the first 4 parameter registers
93 SaveFirstSeven - Save the first 7 parameter registers
94 SetLabel - Set a label in the code section
95 SetRegisterToMinusOne - Set the specified register to -1
96 SetZF - Set the zero flag
97 Start - Initialize the assembler
98 StatSize - Stat a file whose name is addressed by rax to get its size in rax
99 Structure - Create a structure addressed by a register
100 Structure::field - Add a field of the specified length with an optional comment
101 StructureField::addr - Address a field in a structure
102 UnReorderSyscallRegisters - Recover the initial values in registers that were reordered
103 UnReorderXmmRegisters - Recover the initial values in the xmm registers that were reordered
104 WaitPid - Wait for the pid in rax to complete
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.