~andersk/ubuntu/oneiric/openssl/spurious-reboot

« back to all changes in this revision

Viewing changes to crypto/perlasm/x86nasm.pl

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Martin
  • Date: 2004-05-24 17:02:29 UTC
  • Revision ID: james.westby@ubuntu.com-20040524170229-ixlo08bbbly0xied
Tags: upstream-0.9.7d
ImportĀ upstreamĀ versionĀ 0.9.7d

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/local/bin/perl
 
2
 
 
3
package x86nasm;
 
4
 
 
5
$label="L000";
 
6
 
 
7
%lb=(   'eax',  'al',
 
8
        'ebx',  'bl',
 
9
        'ecx',  'cl',
 
10
        'edx',  'dl',
 
11
        'ax',   'al',
 
12
        'bx',   'bl',
 
13
        'cx',   'cl',
 
14
        'dx',   'dl',
 
15
        );
 
16
 
 
17
%hb=(   'eax',  'ah',
 
18
        'ebx',  'bh',
 
19
        'ecx',  'ch',
 
20
        'edx',  'dh',
 
21
        'ax',   'ah',
 
22
        'bx',   'bh',
 
23
        'cx',   'ch',
 
24
        'dx',   'dh',
 
25
        );
 
26
 
 
27
sub main'asm_init_output { @out=(); }
 
28
sub main'asm_get_output { return(@out); }
 
29
sub main'get_labels { return(@labels); }
 
30
 
 
31
sub main'external_label
 
32
{
 
33
        push(@labels,@_);
 
34
        foreach (@_) {
 
35
                push(@out, "extern\t_$_\n");
 
36
        }
 
37
}
 
38
 
 
39
sub main'LB
 
40
        {
 
41
        (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
 
42
        return($lb{$_[0]});
 
43
        }
 
44
 
 
45
sub main'HB
 
46
        {
 
47
        (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
 
48
        return($hb{$_[0]});
 
49
        }
 
50
 
 
51
sub main'BP
 
52
        {
 
53
        &get_mem("BYTE",@_);
 
54
        }
 
55
 
 
56
sub main'DWP
 
57
        {
 
58
        &get_mem("DWORD",@_);
 
59
        }
 
60
 
 
61
sub main'BC
 
62
        {
 
63
        return "BYTE @_";
 
64
        }
 
65
 
 
66
sub main'DWC
 
67
        {
 
68
        return "DWORD @_";
 
69
        }
 
70
 
 
71
sub main'stack_push
 
72
        {
 
73
        my($num)=@_;
 
74
        $stack+=$num*4;
 
75
        &main'sub("esp",$num*4);
 
76
        }
 
77
 
 
78
sub main'stack_pop
 
79
        {
 
80
        my($num)=@_;
 
81
        $stack-=$num*4;
 
82
        &main'add("esp",$num*4);
 
83
        }
 
84
 
 
85
sub get_mem
 
86
        {
 
87
        my($size,$addr,$reg1,$reg2,$idx)=@_;
 
88
        my($t,$post);
 
89
        my($ret)="[";
 
90
        $addr =~ s/^\s+//;
 
91
        if ($addr =~ /^(.+)\+(.+)$/)
 
92
                {
 
93
                $reg2=&conv($1);
 
94
                $addr="_$2";
 
95
                }
 
96
        elsif ($addr =~ /^[_a-zA-Z]/)
 
97
                {
 
98
                $addr="_$addr";
 
99
                }
 
100
 
 
101
        if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; }
 
102
 
 
103
        $reg1="$regs{$reg1}" if defined($regs{$reg1});
 
104
        $reg2="$regs{$reg2}" if defined($regs{$reg2});
 
105
        if (($addr ne "") && ($addr ne 0))
 
106
                {
 
107
                if ($addr !~ /^-/)
 
108
                        { $ret.="${addr}+"; }
 
109
                else    { $post=$addr; }
 
110
                }
 
111
        if ($reg2 ne "")
 
112
                {
 
113
                $t="";
 
114
                $t="*$idx" if ($idx != 0);
 
115
                $reg1="+".$reg1 if ("$reg1$post" ne "");
 
116
                $ret.="$reg2$t$reg1$post]";
 
117
                }
 
118
        else
 
119
                {
 
120
                $ret.="$reg1$post]"
 
121
                }
 
122
        $ret =~ s/\+\]/]/; # in case $addr was the only argument
 
123
        return($ret);
 
124
        }
 
125
 
 
126
sub main'mov    { &out2("mov",@_); }
 
127
sub main'movb   { &out2("mov",@_); }
 
128
sub main'and    { &out2("and",@_); }
 
129
sub main'or     { &out2("or",@_); }
 
130
sub main'shl    { &out2("shl",@_); }
 
131
sub main'shr    { &out2("shr",@_); }
 
132
sub main'xor    { &out2("xor",@_); }
 
133
sub main'xorb   { &out2("xor",@_); }
 
134
sub main'add    { &out2("add",@_); }
 
135
sub main'adc    { &out2("adc",@_); }
 
136
sub main'sub    { &out2("sub",@_); }
 
137
sub main'rotl   { &out2("rol",@_); }
 
138
sub main'rotr   { &out2("ror",@_); }
 
139
sub main'exch   { &out2("xchg",@_); }
 
140
sub main'cmp    { &out2("cmp",@_); }
 
141
sub main'lea    { &out2("lea",@_); }
 
142
sub main'mul    { &out1("mul",@_); }
 
143
sub main'div    { &out1("div",@_); }
 
144
sub main'dec    { &out1("dec",@_); }
 
145
sub main'inc    { &out1("inc",@_); }
 
146
sub main'jmp    { &out1("jmp",@_); }
 
147
sub main'jmp_ptr { &out1p("jmp",@_); }
 
148
 
 
149
# This is a bit of a kludge: declare all branches as NEAR.
 
150
sub main'je     { &out1("je NEAR",@_); }
 
151
sub main'jle    { &out1("jle NEAR",@_); }
 
152
sub main'jz     { &out1("jz NEAR",@_); }
 
153
sub main'jge    { &out1("jge NEAR",@_); }
 
154
sub main'jl     { &out1("jl NEAR",@_); }
 
155
sub main'ja     { &out1("ja NEAR",@_); }
 
156
sub main'jae    { &out1("jae NEAR",@_); }
 
157
sub main'jb     { &out1("jb NEAR",@_); }
 
158
sub main'jbe    { &out1("jbe NEAR",@_); }
 
159
sub main'jc     { &out1("jc NEAR",@_); }
 
160
sub main'jnc    { &out1("jnc NEAR",@_); }
 
161
sub main'jnz    { &out1("jnz NEAR",@_); }
 
162
sub main'jne    { &out1("jne NEAR",@_); }
 
163
sub main'jno    { &out1("jno NEAR",@_); }
 
164
 
 
165
sub main'push   { &out1("push",@_); $stack+=4; }
 
166
sub main'pop    { &out1("pop",@_); $stack-=4; }
 
167
sub main'bswap  { &out1("bswap",@_); &using486(); }
 
168
sub main'not    { &out1("not",@_); }
 
169
sub main'call   { &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); }
 
170
sub main'ret    { &out0("ret"); }
 
171
sub main'nop    { &out0("nop"); }
 
172
 
 
173
sub out2
 
174
        {
 
175
        my($name,$p1,$p2)=@_;
 
176
        my($l,$t);
 
177
 
 
178
        push(@out,"\t$name\t");
 
179
        $t=&conv($p1).",";
 
180
        $l=length($t);
 
181
        push(@out,$t);
 
182
        $l=4-($l+9)/8;
 
183
        push(@out,"\t" x $l);
 
184
        push(@out,&conv($p2));
 
185
        push(@out,"\n");
 
186
        }
 
187
 
 
188
sub out0
 
189
        {
 
190
        my($name)=@_;
 
191
 
 
192
        push(@out,"\t$name\n");
 
193
        }
 
194
 
 
195
sub out1
 
196
        {
 
197
        my($name,$p1)=@_;
 
198
        my($l,$t);
 
199
        push(@out,"\t$name\t".&conv($p1)."\n");
 
200
        }
 
201
 
 
202
sub conv
 
203
        {
 
204
        my($p)=@_;
 
205
        $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
 
206
        return $p;
 
207
        }
 
208
 
 
209
sub using486
 
210
        {
 
211
        return if $using486;
 
212
        $using486++;
 
213
        grep(s/\.386/\.486/,@out);
 
214
        }
 
215
 
 
216
sub main'file
 
217
        {
 
218
        push(@out, "segment .text use32\n");
 
219
        }
 
220
 
 
221
sub main'function_begin
 
222
        {
 
223
        my($func,$extra)=@_;
 
224
 
 
225
        push(@labels,$func);
 
226
        my($tmp)=<<"EOF";
 
227
global  _$func
 
228
_$func:
 
229
        push    ebp
 
230
        push    ebx
 
231
        push    esi
 
232
        push    edi
 
233
EOF
 
234
        push(@out,$tmp);
 
235
        $stack=20;
 
236
        }
 
237
 
 
238
sub main'function_begin_B
 
239
        {
 
240
        my($func,$extra)=@_;
 
241
        my($tmp)=<<"EOF";
 
242
global  _$func
 
243
_$func:
 
244
EOF
 
245
        push(@out,$tmp);
 
246
        $stack=4;
 
247
        }
 
248
 
 
249
sub main'function_end
 
250
        {
 
251
        my($func)=@_;
 
252
 
 
253
        my($tmp)=<<"EOF";
 
254
        pop     edi
 
255
        pop     esi
 
256
        pop     ebx
 
257
        pop     ebp
 
258
        ret
 
259
EOF
 
260
        push(@out,$tmp);
 
261
        $stack=0;
 
262
        %label=();
 
263
        }
 
264
 
 
265
sub main'function_end_B
 
266
        {
 
267
        $stack=0;
 
268
        %label=();
 
269
        }
 
270
 
 
271
sub main'function_end_A
 
272
        {
 
273
        my($func)=@_;
 
274
 
 
275
        my($tmp)=<<"EOF";
 
276
        pop     edi
 
277
        pop     esi
 
278
        pop     ebx
 
279
        pop     ebp
 
280
        ret
 
281
EOF
 
282
        push(@out,$tmp);
 
283
        }
 
284
 
 
285
sub main'file_end
 
286
        {
 
287
        }
 
288
 
 
289
sub main'wparam
 
290
        {
 
291
        my($num)=@_;
 
292
 
 
293
        return(&main'DWP($stack+$num*4,"esp","",0));
 
294
        }
 
295
 
 
296
sub main'swtmp
 
297
        {
 
298
        return(&main'DWP($_[0]*4,"esp","",0));
 
299
        }
 
300
 
 
301
# Should use swtmp, which is above esp.  Linix can trash the stack above esp
 
302
#sub main'wtmp
 
303
#       {
 
304
#       my($num)=@_;
 
305
#
 
306
#       return(&main'DWP(-(($num+1)*4),"esp","",0));
 
307
#       }
 
308
 
 
309
sub main'comment
 
310
        {
 
311
        foreach (@_)
 
312
                {
 
313
                push(@out,"\t; $_\n");
 
314
                }
 
315
        }
 
316
 
 
317
sub main'label
 
318
        {
 
319
        if (!defined($label{$_[0]}))
 
320
                {
 
321
                $label{$_[0]}="\$${label}${_[0]}";
 
322
                $label++;
 
323
                }
 
324
        return($label{$_[0]});
 
325
        }
 
326
 
 
327
sub main'set_label
 
328
        {
 
329
        if (!defined($label{$_[0]}))
 
330
                {
 
331
                $label{$_[0]}="\$${label}${_[0]}";
 
332
                $label++;
 
333
                }
 
334
        push(@out,"$label{$_[0]}:\n");
 
335
        }
 
336
 
 
337
sub main'data_word
 
338
        {
 
339
        push(@out,"\tDD\t$_[0]\n");
 
340
        }
 
341
 
 
342
sub out1p
 
343
        {
 
344
        my($name,$p1)=@_;
 
345
        my($l,$t);
 
346
 
 
347
        push(@out,"\t$name\t ".&conv($p1)."\n");
 
348
        }
 
349
 
 
350
sub main'picmeup
 
351
        {
 
352
        local($dst,$sym)=@_;
 
353
        &main'lea($dst,&main'DWP($sym));
 
354
        }
 
355
 
 
356
sub main'blindpop { &out1("pop",@_); }