You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
3.3 KiB
249 lines
3.3 KiB
#!/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'jnz { &out1("jnz",@_); } |
|
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'function_end_A |
|
{ |
|
local($func)=@_; |
|
|
|
print <<"EOF"; |
|
pop edi |
|
pop esi |
|
pop ebx |
|
pop ebp |
|
ret |
|
EOF |
|
} |
|
|
|
sub main'function_end_B |
|
{ |
|
local($func)=@_; |
|
|
|
print <<"EOF"; |
|
_$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"; |
|
}
|
|
|