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