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