254 lines
3.7 KiB
Perl
254 lines
3.7 KiB
Perl
#!/usr/local/bin/perl
|
|
|
|
package x86ms;
|
|
|
|
$label="L000";
|
|
|
|
$align=($main'aout)?"4":"16";
|
|
$under=($main'aout)?"_":"";
|
|
$com_start=($main'sol)?"/":"#";
|
|
|
|
if ($main'cpp)
|
|
{
|
|
$align="ALIGN";
|
|
$under="";
|
|
$com_start='/*';
|
|
$com_end='*/';
|
|
}
|
|
|
|
%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',
|
|
);
|
|
|
|
%regs=( 'eax', '%eax',
|
|
'ebx', '%ebx',
|
|
'ecx', '%ecx',
|
|
'edx', '%edx',
|
|
'esi', '%esi',
|
|
'edi', '%edi',
|
|
'ebp', '%ebp',
|
|
'esp', '%esp',
|
|
);
|
|
|
|
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)=@_;
|
|
|
|
|
|
$ret="";
|
|
|
|
$addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
|
|
|
|
$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 "")
|
|
{
|
|
$ret.="($reg1,$reg2,$idx)";
|
|
}
|
|
else
|
|
{
|
|
$ret.="($reg1)"
|
|
}
|
|
return($ret);
|
|
}
|
|
|
|
sub main'mov { &out2("movl",@_); }
|
|
sub main'movb { &out2("movb",@_); }
|
|
sub main'and { &out2("andl",@_); }
|
|
sub main'or { &out2("orl",@_); }
|
|
sub main'shl { &out2("shll",@_); }
|
|
sub main'shr { &out2("shrl",@_); }
|
|
sub main'xor { &out2("xorl",@_); }
|
|
sub main'add { &out2("addl",@_); }
|
|
sub main'sub { &out2("subl",@_); }
|
|
sub main'rotl { &out2("roll",@_); }
|
|
sub main'rotr { &out2("rorl",@_); }
|
|
sub main'exch { &out2("xchg",@_); }
|
|
sub main'cmp { &out2("cmpl",@_); }
|
|
sub main'jmp { &out1("jmp",@_); }
|
|
sub main'je { &out1("je",@_); }
|
|
sub main'jne { &out1("jne",@_); }
|
|
sub main'jnz { &out1("jnz",@_); }
|
|
sub main'dec { &out1("decl",@_); }
|
|
sub main'push { &out1("pushl",@_); }
|
|
sub main'call { &out1("call",$under.$_[0]); }
|
|
|
|
|
|
sub out2
|
|
{
|
|
local($name,$p1,$p2)=@_;
|
|
local($l,$ll,$t);
|
|
|
|
print "\t$name\t";
|
|
$t=&conv($p2).",";
|
|
$l=length($t);
|
|
print $t;
|
|
$ll=4-($l+9)/8;
|
|
print "\t" x $ll;
|
|
print &conv($p1);
|
|
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/;
|
|
|
|
$p=$regs{$p} if (defined($regs{$p}));
|
|
|
|
$p =~ s/^([0-9A-Fa-f]+)$/\$$1/;
|
|
$p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
|
|
return $p;
|
|
}
|
|
|
|
sub main'file
|
|
{
|
|
local($file)=@_;
|
|
|
|
print <<"EOF";
|
|
.file "$file.s"
|
|
.version "01.01"
|
|
gcc2_compiled.:
|
|
EOF
|
|
}
|
|
|
|
sub main'function_begin
|
|
{
|
|
local($func,$num)=@_;
|
|
|
|
$params=$num*4;
|
|
|
|
$func=$under.$func;
|
|
|
|
print <<"EOF";
|
|
.text
|
|
.align $align
|
|
.globl $func
|
|
EOF
|
|
if ($main'cpp)
|
|
{ printf("\tTYPE($func,\@function)\n"); }
|
|
else { printf("\t.type $func,\@function\n"); }
|
|
print <<"EOF";
|
|
$func:
|
|
pushl %ebp
|
|
pushl %ebx
|
|
pushl %esi
|
|
pushl %edi
|
|
|
|
EOF
|
|
$stack=20;
|
|
}
|
|
|
|
sub main'function_end
|
|
{
|
|
local($func)=@_;
|
|
|
|
$func=$under.$func;
|
|
|
|
print <<"EOF";
|
|
popl %edi
|
|
popl %esi
|
|
popl %ebx
|
|
popl %ebp
|
|
ret
|
|
.${func}_end:
|
|
EOF
|
|
if ($main'cpp)
|
|
{ printf("\tSIZE($func,.${func}_end-$func)\n"); }
|
|
else { printf("\t.size\t$func,.${func}_end-$func\n"); }
|
|
print ".ident \"desasm.pl\"\n";
|
|
$stack=0;
|
|
%label=();
|
|
}
|
|
|
|
|
|
sub main'wparam
|
|
{
|
|
local($num)=@_;
|
|
|
|
return(&main'DWP($stack+$num*4,"esp","",0));
|
|
}
|
|
|
|
sub main'wtmp
|
|
{
|
|
local($num)=@_;
|
|
|
|
return(&main'DWP(-($num+1)*4,"esp","",0));
|
|
}
|
|
|
|
sub main'comment
|
|
{
|
|
foreach (@_)
|
|
{
|
|
if (/^\s*$/)
|
|
{ print "\n"; }
|
|
else
|
|
{ print "\t$com_start $_ $com_end\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 ".align $align\n";
|
|
print "$label{$_[0]}:\n";
|
|
}
|
|
|
|
sub main'file_end
|
|
{
|
|
}
|