#!/usr/local/bin/perl
-# Because the bswapl instruction is not supported for old assembers
-# (it was a new instruction for the 486), I've added .byte xxxx code
-# to put it in.
-# eric 24-Apr-1998
-#
-
package x86unix;
$label="L000";
+$const="";
+$constl=0;
$align=($main'aout)?"4":"16";
$under=($main'aout)?"_":"";
return(&main'DWP(@_));
}
+sub main'BC
+ {
+ return @_;
+ }
+
+sub main'DWC
+ {
+ return @_;
+ }
+
#sub main'BP
# {
# local($addr,$reg1,$reg2,$idx)=@_;
sub main'inc { &out1("incl",@_); }
sub main'push { &out1("pushl",@_); $stack+=4; }
sub main'pop { &out1("popl",@_); $stack-=4; }
-sub main'bswap { &out1("bswapl",@_); }
sub main'not { &out1("notl",@_); }
sub main'call { &out1("call",$under.$_[0]); }
sub main'ret { &out0("ret"); }
sub main'nop { &out0("nop"); }
+# The bswapl instruction is new for the 486. Emulate if i386.
+sub main'bswap
+ {
+ if ($main'i386)
+ {
+ &main'comment("bswapl @_");
+ &main'exch(main'HB(@_),main'LB(@_));
+ &main'rotr(@_,16);
+ &main'exch(main'HB(@_),main'LB(@_));
+ }
+ else
+ {
+ &out1("bswapl",@_);
+ }
+ }
+
sub out2
{
local($name,$p1,$p2)=@_;
push(@out,$tmp);
if ($main'cpp)
{ $tmp=push(@out,"\tTYPE($func,\@function)\n"); }
+ elsif ($main'gaswin)
+ { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
else { $tmp=push(@out,"\t.type\t$func,\@function\n"); }
push(@out,"$func:\n");
$tmp=<<"EOF";
push(@out,$tmp);
if ($main'cpp)
{ push(@out,"\tTYPE($func,\@function)\n"); }
+ elsif ($main'gaswin)
+ { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
else { push(@out,"\t.type $func,\@function\n"); }
push(@out,"$func:\n");
$stack=4;
popl %ebx
popl %ebp
ret
+$const
.${func}_end:
EOF
push(@out,$tmp);
+ $const="";
+
if ($main'cpp)
{ push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
+ elsif ($main'gaswin)
+ { $tmp=push(@out,"\t.align 4\n"); }
else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
push(@out,".ident \"$func\"\n");
$stack=0;
$func=$under.$func;
- push(@out,".${func}_end:\n");
+ push(@out,".L_${func}_end:\n");
if ($main'cpp)
- { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
- else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
+ { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); }
+ elsif ($main'gaswin)
+ { push(@out,"\t.align 4\n"); }
+ else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); }
push(@out,".ident \"desasm.pl\"\n");
$stack=0;
%label=();
{
push(@out,"\t.long $_[0]\n");
}
+
+# debug output functions: puts, putx, printf
+
+sub main'puts
+ {
+ &pushvars();
+ &main'push('$Lstring' . ++$constl);
+ &main'call('puts');
+ $stack-=4;
+ &main'add("esp",4);
+ &popvars();
+
+ $const .= "Lstring$constl:\n\t.string \"@_[0]\"\n";
+ }
+
+sub main'putx
+ {
+ &pushvars();
+ &main'push($_[0]);
+ &main'push('$Lstring' . ++$constl);
+ &main'call('printf');
+ &main'add("esp",8);
+ $stack-=8;
+ &popvars();
+
+ $const .= "Lstring$constl:\n\t.string \"\%X\"\n";
+ }
+
+sub main'printf
+ {
+ $ostack = $stack;
+ &pushvars();
+ for ($i = @_ - 1; $i >= 0; $i--)
+ {
+ if ($i == 0) # change this to support %s format strings
+ {
+ &main'push('$Lstring' . ++$constl);
+ $const .= "Lstring$constl:\n\t.string \"@_[$i]\"\n";
+ }
+ else
+ {
+ if ($_[$i] =~ /([0-9]*)\(%esp\)/)
+ {
+ &main'push(($1 + $stack - $ostack) . '(%esp)');
+ }
+ else
+ {
+ &main'push($_[$i]);
+ }
+ }
+ }
+ &main'call('printf');
+ $stack-=4*@_;
+ &main'add("esp",4*@_);
+ &popvars();
+ }
+
+sub pushvars
+ {
+ &main'push("edx");
+ &main'push("ecx");
+ &main'push("eax");
+ }
+
+sub popvars
+ {
+ &main'pop("eax");
+ &main'pop("ecx");
+ &main'pop("edx");
+ }