README.md
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