my $elf=1; $elf=0 if (!$gas);
my $win64=0;
my $prefix="";
+my $decor=".L";
my $masmref=8 + 50727*2**-32; # 8.00.50727 shipped with VS2005
my $masm=0;
my $nasm=0;
if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1; $prefix="_"; }
-elsif ($flavour eq "macosx") { $gas=1; $elf=0; $prefix="_"; }
-elsif ($flavour eq "masm") { $gas=0; $elf=0; $masm=$masmref; $win64=1; }
-elsif ($flavour eq "nasm") { $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $PTR=""; }
+elsif ($flavour eq "macosx") { $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
+elsif ($flavour eq "masm") { $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
+elsif ($flavour eq "nasm") { $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
elsif (!$gas)
{ if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
{ $nasm = $1 + $2*0.01; $PTR=""; }
die "no assembler found on %PATH" if (!($nasm || $masm));
$win64=1;
$elf=0;
+ $decor="\$L\$";
}
my $current_segment;
$self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
sprintf "\$%s",$self->{value};
} else {
- $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig;
+ $self->{value} =~ s/(0b[0-1]+)/oct($1)/eig;
+ $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig if ($masm);
sprintf "%s",$self->{value};
}
}
my $sz = shift;
$self->{label} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
+ $self->{label} =~ s/\.L/$decor/g;
# Silently convert all EAs to 64-bit. This is required for
# elder GNU assembler and results in more compact code,
# in $self->{label}
$self->{label} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi;
$self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
- $self->{label} =~ s/\.L/L\$/g if (!$elf);
+ $self->{label} =~ s/^___imp_/__imp__/ if ($flavour eq "mingw64");
if (defined($self->{index})) {
sprintf "%s%s(%%%s,%%%s,%d)",$self->{asterisk},
} else {
%szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR", q=>"QWORD$PTR" );
- $self->{label} =~ s/\.L/\$L\$/g;
$self->{label} =~ s/\./\$/g;
$self->{label} =~ s/0x([0-9a-f]+)/0$1h/ig;
$self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/);
$ret = $self;
$line = substr($line,@+[0]); $line =~ s/^\s+//;
- $self->{value} =~ s/\.L/\$L\$/ if (!$gas);
- $self->{value} =~ s/\.L/L\$/ if (!$elf);
+ $self->{value} =~ s/^\.L/$decor/;
}
$ret;
}
$func .= " movq %rdi,8(%rsp)\n";
$func .= " movq %rsi,16(%rsp)\n";
$func .= " movq %rsp,%rax\n";
- $func .= ".LSEH_begin_$current_function->{name}:\n";
+ $func .= "${decor}SEH_begin_$current_function->{name}:\n";
my $narg = $current_function->{narg};
$narg=6 if (!defined($narg));
$func .= " movq %rcx,%rdi\n" if ($narg>0);
$func .= " mov QWORD${PTR}[8+rsp],rdi\t;WIN64 prologue\n";
$func .= " mov QWORD${PTR}[16+rsp],rsi\n";
$func .= " mov rax,rsp\n";
- $func .= "\$L\$SEH_begin_$current_function->{name}:";
+ $func .= "${decor}SEH_begin_$current_function->{name}:";
$func .= ":" if ($masm);
$func .= "\n";
my $narg = $current_function->{narg};
$self->{value} =~ s/\@PLT// if (!$elf);
$self->{value} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
- $self->{value} =~ s/\.L/\$L\$/g if (!$gas);
- $self->{value} =~ s/\.L/L\$/g if (!$elf);
+ $self->{value} =~ s/\.L/$decor/g;
}
$ret;
}
}
last;
};
+ /\.rva|\.long|\.quad/
+ && do { $line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
+ $line =~ s/\.L/$decor/g;
+ last;
+ };
}
if ($gas) {
} elsif (!$elf && $dir =~ /\.size/) {
$self->{value} = "";
if (defined($current_function)) {
- $self->{value} .= ".LSEH_end_$current_function->{name}:"
+ $self->{value} .= "${decor}SEH_end_$current_function->{name}:"
if ($win64 && $current_function->{abi} eq "svr4");
undef $current_function;
}
/\.size/ && do { if (defined($current_function)) {
undef $self->{value};
if ($current_function->{abi} eq "svr4") {
- $self->{value}="\$L\$SEH_end_$current_function->{name}:";
+ $self->{value}="${decor}SEH_end_$current_function->{name}:";
$self->{value}.=":\n" if($masm);
}
$self->{value}.="$current_function->{name}\tENDP" if($masm);
my @arr = split(',',$line);
my $last = pop(@arr);
my $conv = sub { my $var=shift;
- $var=~s/0x([0-9a-f]+)/0$1h/ig;
- $var=~s/\.L/\$L\$/g;
+ $var=~s/(0b[0-1]+)/oct($1)/eig;
+ $var=~s/0x([0-9a-f]+)/0$1h/ig if ($masm);
if ($sz eq "D" && ($current_segment=~/.[px]data/ || $dir eq ".rva"))
{ $var=~s/([_a-z\$\@][_a-z0-9\$\@]*)/$nasm?"$1 wrt ..imagebase":"imagerel $1"/egi; }
$var;
last;
};
/\.byte/ && do { my @str=split(",",$line);
+ map(s/(0b[0-1]+)/oct($1)/eig,@str);
+ map(s/0x([0-9a-f]+)/0$1h/ig,@str) if ($masm);
while ($#str>15) {
$self->{value}.="DB\t"
.join(",",@str[0..15])."\n";
undef $label;
undef $opcode;
- undef $dst;
- undef $src;
undef $sz;
+ undef @args;
if ($label=label->re(\$line)) { print $label->out(); }
if (directive->re(\$line)) {
printf "%s",directive->out();
- } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: {
+ } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: while (1) {
+ my $arg;
- if ($src=register->re(\$line)) { opcode->size($src->size()); }
- elsif ($src=const->re(\$line)) { }
- elsif ($src=ea->re(\$line)) { }
- elsif ($src=expr->re(\$line)) { }
+ if ($arg=register->re(\$line)) { opcode->size($arg->size()); }
+ elsif ($arg=const->re(\$line)) { }
+ elsif ($arg=ea->re(\$line)) { }
+ elsif ($arg=expr->re(\$line)) { }
+ else { last ARGUMENT; }
- last ARGUMENT if ($line !~ /^,/);
+ push @args,$arg;
- $line = substr($line,1); $line =~ s/^\s+//;
-
- if ($dst=register->re(\$line)) { opcode->size($dst->size()); }
- elsif ($dst=const->re(\$line)) { }
- elsif ($dst=ea->re(\$line)) { }
+ last ARGUMENT if ($line !~ /^,/);
+ $line =~ s/^,\s*//;
} # ARGUMENT:
$sz=opcode->size();
- if (defined($dst)) {
+ if ($#args>=0) {
+ my $insn;
if ($gas) {
- printf "\t%s\t%s,%s", $opcode->out($dst->size()),
- $src->out($sz),$dst->out($sz);
+ $insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
} else {
+ $insn = $opcode->out();
+ @args = reverse(@args);
undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
- printf "\t%s\t%s,%s", $opcode->out(),
- $dst->out($sz),$src->out($sz);
}
- } elsif (defined($src)) {
- printf "\t%s\t%s",$opcode->out(),$src->out($sz);
+ printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
} else {
printf "\t%s",$opcode->out();
}