7 $::lbdecor
="\$L"; # local label decoration
8 $nmdecor="_"; # external name decoration
14 { my ($opcode,@arg)=@_;
16 # fix hexadecimal constants
17 for (@arg) { s/0x([0-9a-f]+)/0$1h/oi; }
19 if ($opcode !~ /movq/)
20 { # fix xmm references
21 $arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i);
22 $arg[1] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[0]=~/\bxmm[0-7]\b/i);
25 &::emit
($opcode,@arg);
29 # opcodes not covered by ::generic above, mostly inconsistent namings...
31 sub ::call
{ &::emit
("call",(&::islabel
($_[0]) or "$nmdecor$_[0]")); }
32 sub ::call_ptr
{ &::emit
("call",@_); }
33 sub ::jmp_ptr
{ &::emit
("jmp",@_); }
36 { my($size,$addr,$reg1,$reg2,$idx)=@_;
39 $ret .= "$size PTR " if ($size ne "");
42 # prepend global references with optional underscore
43 $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
44 # put address arithmetic expression in parenthesis
45 $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/);
47 if (($addr ne "") && ($addr ne 0))
48 { if ($addr !~ /^-/) { $ret .= "$addr"; }
56 $ret .= "+$reg1" if ($reg1 ne "");
62 $ret =~ s/\+\]/]/; # in case $addr was the only argument
67 sub ::BP
{ &get_mem
("BYTE",@_); }
68 sub ::DWP
{ &get_mem
("DWORD",@_); }
69 sub ::QWP
{ &get_mem
("QWORD",@_); }
77 ECHO MASM version
8.00 or later is strongly recommended
.
83 .text\
$ SEGMENT PAGE
'CODE'
85 .text\
$ SEGMENT ALIGN
(64) 'CODE'
92 sub ::function_begin_B
94 my $global=($func !~ /^_/);
95 my $begin="${::lbdecor}_${func}_begin";
97 &::LABEL
($func,$global?
"$begin":"$nmdecor$func");
98 $func="ALIGN\t16\n".$nmdecor.$func."\tPROC";
100 if ($global) { $func.=" PUBLIC\n${begin}::\n"; }
101 else { $func.=" PRIVATE\n"; }
108 push(@out,"$nmdecor$func ENDP\n");
114 { my $xmmheader=<<___
;
123 if (grep {/\b[x]?mm[0-7]\b/i} @out) {
124 grep {s/\.[3-7]86/$xmmheader/} @out;
127 push(@out,"$segment ENDS\n");
129 if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
132 COMM
${nmdecor
}OPENSSL_ia32cap_P
:QWORD
135 # comment out OPENSSL_ia32cap_P declarations
136 grep {s/(^EXTERN\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
139 push (@out,$initseg) if ($initseg);
143 sub ::comment
{ foreach (@_) { push(@out,"\t; $_\n"); } }
146 { my $l=shift; push(@out,$l.($l=~/^\Q${::lbdecor}\E[0-9]{3}/?
":\n":"::\n")); };
150 { push(@out, "EXTERN\t".&::LABEL
($_,$nmdecor.$_).":NEAR\n"); }
154 { push(@out,"PUBLIC\t".&::LABEL
($_[0],$nmdecor.$_[0])."\n"); }
157 { push(@out,("DB\t").join(',',@_)."\n"); }
160 { push(@out,("DD\t").join(',',@_)."\n"); }
163 { push(@out,"ALIGN\t$_[0]\n"); }
167 &::lea
($dst,&::DWP
($sym));
171 { my $f=$nmdecor.shift;
174 .CRT\
$XCU SEGMENT DWORD PUBLIC
'DATA'
182 { push(@out,"$segment\tENDS\n_DATA\tSEGMENT\n"); $segment="_DATA"; }