224 lines
3.1 KiB
Perl
224 lines
3.1 KiB
Perl
#!/usr/local/bin/perl
|
|
|
|
package x86ms;
|
|
|
|
$label="L000";
|
|
|
|
%lb=( 'eax', 'al',
|
|
'ebx', 'bl',
|
|
'ecx', 'cl',
|
|
'edx', 'dl',
|
|
'ax', 'al',
|
|
'bx', 'bl',
|
|
'cx', 'cl',
|
|
'dx', 'dl',
|
|
);
|
|
|
|
%hb=( 'eax', 'ah',
|
|
'ebx', 'bh',
|
|
'ecx', 'ch',
|
|
'edx', 'dh',
|
|
'ax', 'ah',
|
|
'bx', 'bh',
|
|
'cx', 'ch',
|
|
'dx', 'dh',
|
|
);
|
|
|
|
sub main'LB
|
|
{
|
|
(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
|
|
return($lb{$_[0]});
|
|
}
|
|
|
|
sub main'HB
|
|
{
|
|
(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
|
|
return($hb{$_[0]});
|
|
}
|
|
|
|
sub main'DWP
|
|
{
|
|
local($addr,$reg1,$reg2,$idx)=@_;
|
|
local($t);
|
|
local($ret)="DWORD PTR ";
|
|
|
|
$addr =~ s/^\s+//;
|
|
if ($addr =~ /^(.+)\+(.+)$/)
|
|
{
|
|
$reg2=&conv($1);
|
|
$addr="_$2";
|
|
}
|
|
elsif ($addr =~ /^[_a-zA-Z]/)
|
|
{
|
|
$addr="_$addr";
|
|
}
|
|
|
|
$reg1="$regs{$reg1}" if defined($regs{$reg1});
|
|
$reg2="$regs{$reg2}" if defined($regs{$reg2});
|
|
$ret.=$addr if ($addr ne "") && ($addr ne 0);
|
|
if ($reg2 ne "")
|
|
{
|
|
$t="";
|
|
$t="*$idx" if ($idx != 0);
|
|
$ret.="[$reg2$t+$reg1]";
|
|
}
|
|
else
|
|
{
|
|
$ret.="[$reg1]"
|
|
}
|
|
return($ret);
|
|
}
|
|
|
|
sub main'mov { &out2("mov",@_); }
|
|
sub main'movb { &out2("mov",@_); }
|
|
sub main'and { &out2("and",@_); }
|
|
sub main'or { &out2("or",@_); }
|
|
sub main'shl { &out2("shl",@_); }
|
|
sub main'shr { &out2("shr",@_); }
|
|
sub main'xor { &out2("xor",@_); }
|
|
sub main'add { &out2("add",@_); }
|
|
sub main'sub { &out2("sub",@_); }
|
|
sub main'rotl { &out2("rol",@_); }
|
|
sub main'rotr { &out2("ror",@_); }
|
|
sub main'exch { &out2("xchg",@_); }
|
|
sub main'cmp { &out2("cmp",@_); }
|
|
sub main'dec { &out1("dec",@_); }
|
|
sub main'jmp { &out1("jmp",@_); }
|
|
sub main'je { &out1("je",@_); }
|
|
sub main'jz { &out1("jz",@_); }
|
|
sub main'push { &out1("push",@_); }
|
|
sub main'call { &out1("call",'_'.$_[0]); }
|
|
|
|
|
|
sub out2
|
|
{
|
|
local($name,$p1,$p2)=@_;
|
|
local($l,$t);
|
|
|
|
print "\t$name\t";
|
|
$t=&conv($p1).",";
|
|
$l=length($t);
|
|
print $t;
|
|
$l=4-($l+9)/8;
|
|
print "\t" x $l;
|
|
print &conv($p2);
|
|
print "\n";
|
|
}
|
|
|
|
sub out1
|
|
{
|
|
local($name,$p1)=@_;
|
|
local($l,$t);
|
|
|
|
print "\t$name\t";
|
|
print &conv($p1);
|
|
print "\n";
|
|
}
|
|
|
|
sub conv
|
|
{
|
|
local($p)=@_;
|
|
|
|
$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
|
|
return $p;
|
|
}
|
|
|
|
sub main'file
|
|
{
|
|
local($file)=@_;
|
|
|
|
print <<"EOF";
|
|
TITLE $file.asm
|
|
.386
|
|
.model FLAT
|
|
EOF
|
|
}
|
|
|
|
sub main'function_begin
|
|
{
|
|
local($func,$num)=@_;
|
|
|
|
$params=$num*4;
|
|
|
|
print <<"EOF";
|
|
_TEXT SEGMENT
|
|
PUBLIC _$func
|
|
EXTRN _des_SPtrans:DWORD
|
|
_$func PROC NEAR
|
|
push ebp
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
EOF
|
|
$stack=20;
|
|
}
|
|
|
|
sub main'function_end
|
|
{
|
|
local($func)=@_;
|
|
|
|
print <<"EOF";
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
pop ebp
|
|
ret
|
|
_$func ENDP
|
|
_TEXT ENDS
|
|
EOF
|
|
$stack=0;
|
|
%label=();
|
|
}
|
|
|
|
sub main'file_end
|
|
{
|
|
print "END\n"
|
|
}
|
|
|
|
sub main'wparam
|
|
{
|
|
local($num)=@_;
|
|
|
|
return(&main'DWP($stack+$num*4,"esp","",0));
|
|
}
|
|
|
|
sub main'wtmp
|
|
{
|
|
local($num)=@_;
|
|
|
|
return(&main'DWP($stack+$params+$num*4,"esp","",0));
|
|
}
|
|
|
|
sub main'comment
|
|
{
|
|
foreach (@_)
|
|
{
|
|
print "\t; $_\n";
|
|
}
|
|
}
|
|
|
|
sub main'label
|
|
{
|
|
if (!defined($label{$_[0]}))
|
|
{
|
|
$label{$_[0]}="\$${label}${_[0]}";
|
|
$label++;
|
|
}
|
|
return($label{$_[0]});
|
|
}
|
|
|
|
sub main'set_label
|
|
{
|
|
if (!defined($label{$_[0]}))
|
|
{
|
|
$label{$_[0]}="${label}${_[0]}";
|
|
$label++;
|
|
}
|
|
print "$label{$_[0]}:\n";
|
|
}
|
|
|
|
sub main'file_end
|
|
{
|
|
print "END\n";
|
|
}
|