1Perl scripts for assembler sources
2==================================
3
4The perl scripts in this directory are my 'hack' to generate
5multiple different assembler formats via the one original script.
6
7The way to use this library is to start with adding the path to this directory
8and then include it.
9
10    push(@INC,"perlasm","../../perlasm");
11    require "x86asm.pl";
12
13The first thing we do is setup the file and type of assembler
14
15    &asm_init($ARGV[0]);
16
17The first argument is the 'type'.  Currently
18`cpp`, `sol`, `a.out`, `elf` or `win32`.
19The second argument is the file name.
20
21The reciprocal function is
22`&asm_finish()` which should be called at the end.
23
24There are two main 'packages'. `x86ms.pl`, which is the Microsoft assembler,
25and `x86unix.pl` which is the unix (gas) version.
26
27Functions 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
54So 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
66So 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
105The above example is very very unoptimised but gives an idea of how
106things work.
107
108There 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
120So 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);
131