perlasm/x86gas.pl: give a hand old assemblers assembling loop instruction.
[openssl.git] / crypto / perlasm / readme
1 The perl scripts in this directory are my 'hack' to generate
2 multiple different assembler formats via the one origional script.
3
4 The way to use this library is to start with adding the path to this directory
5 and then include it.
6
7 push(@INC,"perlasm","../../perlasm");
8 require "x86asm.pl";
9
10 The first thing we do is setup the file and type of assember
11
12 &asm_init($ARGV[0],$0);
13
14 The first argument is the 'type'.  Currently
15 'cpp', 'sol', 'a.out', 'elf' or 'win32'.
16 Argument 2 is the file name.
17
18 The reciprocal function is
19 &asm_finish() which should be called at the end.
20
21 There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
22 and x86unix.pl which is the unix (gas) version.
23
24 Functions of interest are:
25 &external_label("des_SPtrans"); declare and external variable
26 &LB(reg);                       Low byte for a register
27 &HB(reg);                       High byte for a register
28 &BP(off,base,index,scale)       Byte pointer addressing
29 &DWP(off,base,index,scale)      Word pointer addressing
30 &stack_push(num)                Basically a 'sub esp, num*4' with extra
31 &stack_pop(num)                 inverse of stack_push
32 &function_begin(name,extra)     Start a function with pushing of
33                                 edi, esi, ebx and ebp.  extra is extra win32
34                                 external info that may be required.
35 &function_begin_B(name,extra)   Same as norma function_begin but no pushing.
36 &function_end(name)             Call at end of function.
37 &function_end_A(name)           Standard pop and ret, for use inside functions
38 &function_end_B(name)           Call at end but with poping or 'ret'.
39 &swtmp(num)                     Address on stack temp word.
40 &wparam(num)                    Parameter number num, that was push
41                                 in C convention.  This all works over pushes
42                                 and pops.
43 &comment("hello there")         Put in a comment.
44 &label("loop")                  Refer to a label, normally a jmp target.
45 &set_label("loop")              Set a label at this point.
46 &data_word(word)                Put in a word of data.
47
48 So how does this all hold together?  Given
49
50 int calc(int len, int *data)
51         {
52         int i,j=0;
53
54         for (i=0; i<len; i++)
55                 {
56                 j+=other(data[i]);
57                 }
58         }
59
60 So a very simple version of this function could be coded as
61
62         push(@INC,"perlasm","../../perlasm");
63         require "x86asm.pl";
64         
65         &asm_init($ARGV[0],"cacl.pl");
66
67         &external_label("other");
68
69         $tmp1=  "eax";
70         $j=     "edi";
71         $data=  "esi";
72         $i=     "ebp";
73
74         &comment("a simple function");
75         &function_begin("calc");
76         &mov(   $data,          &wparam(1)); # data
77         &xor(   $j,             $j);
78         &xor(   $i,             $i);
79
80         &set_label("loop");
81         &cmp(   $i,             &wparam(0));
82         &jge(   &label("end"));
83
84         &mov(   $tmp1,          &DWP(0,$data,$i,4));
85         &push(  $tmp1);
86         &call(  "other");
87         &add(   $j,             "eax");
88         &pop(   $tmp1);
89         &inc(   $i);
90         &jmp(   &label("loop"));
91
92         &set_label("end");
93         &mov(   "eax",          $j);
94
95         &function_end("calc");
96
97         &asm_finish();
98
99 The above example is very very unoptimised but gives an idea of how
100 things work.
101
102 There is also a cbc mode function generator in cbc.pl
103
104 &cbc(   $name,
105         $encrypt_function_name,
106         $decrypt_function_name,
107         $true_if_byte_swap_needed,
108         $parameter_number_for_iv,
109         $parameter_number_for_encrypt_flag,
110         $first_parameter_to_pass,
111         $second_parameter_to_pass,
112         $third_parameter_to_pass);
113
114 So for example, given
115 void BF_encrypt(BF_LONG *data,BF_KEY *key);
116 void BF_decrypt(BF_LONG *data,BF_KEY *key);
117 void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
118         BF_KEY *ks, unsigned char *iv, int enc);
119
120 &cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
121
122 &cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
123 &cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
124