Nasm-X86
view release on metacpan or search on metacpan
lib/Nasm/X86.pm view on Meta::CPAN
sub SaveFirstSeven() # Save the first 7 parameter registers
{Push rax;
Push rdi;
Push rsi;
Push rdx;
Push r10;
Push r8;
Push r9;
7 * RegisterSize(rax); # Space occupied by push
}
sub RestoreFirstSeven() # Restore the first 7 parameter registers
{Pop r9;
Pop r8;
Pop r10;
Pop rdx;
Pop rsi;
Pop rdi;
Pop rax;
}
sub RestoreFirstSevenExceptRax() # Restore the first 7 parameter registers except rax which is being used to return the result
{Pop r9;
Pop r8;
Pop r10;
Pop rdx;
Pop rsi;
Pop rdi;
Add rsp, RegisterSize(rax); # Skip rax
}
sub RestoreFirstSevenExceptRaxAndRdi() # Restore the first 7 parameter registers except rax and rdi which are being used to return the results
{Pop r9;
Pop r8;
Pop r10;
Pop rdx;
Pop rsi;
Add rsp, 2*RegisterSize(rax); # Skip rdi and rax
}
sub RegisterSize($) # Return the size of a register
{my ($r) = @_; # Register
return 16 if $r =~ m(\Ax);
return 32 if $r =~ m(\Ay);
return 64 if $r =~ m(\Az);
8
}
sub ClearRegisters(@) # Clear registers by setting them to zero
{my (@registers) = @_; # Registers
@_ == 1 or confess;
for my $r(@registers)
{my $size = RegisterSize $r;
Xor $r, $r if $size == 8;
Vpxorq $r, $r if $size > 8;
}
}
#D1 Structured Programming # Structured programming constructs
sub If(&;&) # If
{my ($then, $else) = @_; # Then - required , else - optional
@_ >= 1 or confess;
if (@_ == 1) # No else
{Comment "if then";
my $end = Label;
Jz $end;
&$then;
SetLabel $end;
}
else # With else
{Comment "if then else";
my $endIf = Label;
my $startElse = Label;
Jz $startElse;
&$then;
Jmp $endIf;
SetLabel $startElse;
&$else;
SetLabel $endIf;
}
}
sub For(&$$$) # For
{my ($body, $register, $limit, $increment) = @_; # Body, register, limit on loop, increment
@_ == 4 or confess;
Comment "For $register $limit";
my $start = Label;
my $end = Label;
SetLabel $start;
Cmp $register, $limit;
Jge $end;
&$body;
if ($increment == 1)
{Inc $register;
}
else
{Add $register, $increment;
}
Jmp $start;
SetLabel $end;
}
sub 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
{my ($body, %options) = @_; # Body, options.
@_ >= 1 or confess;
my $name = $options{name}; # Optional name for subroutine reuse
my $comment = $options{comment}; # Optional comment
Comment "Subroutine " .($comment//'');
if ($name and my $n = $subroutines{$name}) {return $n} # Return the label of a pre-existing copy of the code
my $start = Label;
my $end = Label;
Jmp $end;
SetLabel $start;
&$body;
Ret;
SetLabel $end;
( run in 3.119 seconds using v1.01-cache-2.11-cpan-364913b4093 )