-
Notifications
You must be signed in to change notification settings - Fork 0
/
rewrite-stringops.pl
68 lines (65 loc) · 1.79 KB
/
rewrite-stringops.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/perl
use strict;
my $label_count = 1;
while (<>) {
if (/^\t(rep(?:e|ne|z|nz|))(?: (\w+))?$/) {
my $repop = $1;
my $stringop;
if ($2) {
$stringop = $2;
} else {
$stringop = <>;
chomp $stringop;
$stringop =~ s/^\t//;
}
if ($stringop eq "ret") {
print "\tret\n";
next;
}
my $head_label = ".LRWSOPS$label_count"; $label_count++;
my $tail_label = ".LRWSOPS$label_count"; $label_count++;
my $save_eax = ($stringop !~ /^stos/);
print "\tpushl\t%eax\n" if $save_eax;
print "$head_label:\n";
print "\tjecxz\t$tail_label\n";
if ($stringop eq "movsl") {
# strcpy
print "\tmovl\t(%esi), %eax\n";
print "\tmovl\t%eax, (%edi)\n";
print "\tleal\t4(%esi), %esi\n";
print "\tleal\t4(%edi), %edi\n";
print "\tleal\t-1(%ecx), %ecx\n";
print "\tjmp\t$head_label\n";
} elsif ($stringop eq "stosl") {
# memset/memzero
print "\tmovl\t%eax, (%edi)\n";
print "\tleal\t4(%edi), %edi\n";
print "\tleal\t-1(%ecx), %ecx\n";
print "\tjmp\t$head_label\n";
} elsif ($repop eq "repz" and $stringop eq "cmpsb") {
# strncmp
print "\tmovb\t(%esi), %al\n";
print "\tcmpb\t%al, (%edi)\n";
print "\tleal\t1(%esi), %esi\n";
print "\tleal\t1(%edi), %edi\n";
print "\tleal\t-1(%ecx), %ecx\n";
print "\tjz\t$head_label\n";
} elsif ($repop eq "repnz" and $stringop eq "scasb") {
# strlen
print "\tcmpb\t%al, (%edi)\n";
print "\tleal\t1(%edi), %edi\n";
print "\tleal\t-1(%ecx), %ecx\n";
print "\tjnz\t$head_label\n";
} else {
die "Unsupported string op $repop $stringop (line $.)\n";
}
print "$tail_label:\n";
print "\tpopl\t%eax\n" if $save_eax;
} elsif (/^\tcld/) {
next;
} elsif (/^\tstd/) {
die "Backwards string ops are not supported";
} else {
print;
}
}