readme revision 225736
150476SpeterThe perl scripts in this directory are my 'hack' to generate
220920Swoschmultiple different assembler formats via the one origional script.
3138970Sglebius
417072SjulianThe way to use this library is to start with adding the path to this directory
579538Sruand then include it.
617072Sjulian
766723Srupush(@INC,"perlasm","../../perlasm");
817072Sjulianrequire "x86asm.pl";
917072Sjulian
1084306SruThe first thing we do is setup the file and type of assember
1184306Sru
1284306Sru&asm_init($ARGV[0],$0);
1317072Sjulian
1417072SjulianThe first argument is the 'type'.  Currently
15162601Sdanger'cpp', 'sol', 'a.out', 'elf' or 'win32'.
16162601SdangerArgument 2 is the file name.
17162601Sdanger
18162601SdangerThe reciprocal function is
19162601Sdanger&asm_finish() which should be called at the end.
20162601Sdanger
21162601SdangerThere are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
22162601Sdangerand x86unix.pl which is the unix (gas) version.
23162601Sdanger
24162601SdangerFunctions of interest are:
25162601Sdanger&external_label("des_SPtrans");	declare and external variable
26162601Sdanger&LB(reg);			Low byte for a register
27162601Sdanger&HB(reg);			High byte for a register
28162601Sdanger&BP(off,base,index,scale)	Byte pointer addressing
29162601Sdanger&DWP(off,base,index,scale)	Word pointer addressing
30162601Sdanger&stack_push(num)		Basically a 'sub esp, num*4' with extra
31162601Sdanger&stack_pop(num)			inverse of stack_push
3217072Sjulian&function_begin(name,extra)	Start a function with pushing of
3317072Sjulian				edi, esi, ebx and ebp.  extra is extra win32
3417072Sjulian				external info that may be required.
3517072Sjulian&function_begin_B(name,extra)	Same as norma function_begin but no pushing.
3617072Sjulian&function_end(name)		Call at end of function.
3717072Sjulian&function_end_A(name)		Standard pop and ret, for use inside functions
3857676Ssheldonh&function_end_B(name)		Call at end but with poping or 'ret'.
3957676Ssheldonh&swtmp(num)			Address on stack temp word.
4017072Sjulian&wparam(num)			Parameter number num, that was push
4117072Sjulian				in C convention.  This all works over pushes
4217072Sjulian				and pops.
4317072Sjulian&comment("hello there")		Put in a comment.
4417072Sjulian&label("loop")			Refer to a label, normally a jmp target.
4517072Sjulian&set_label("loop")		Set a label at this point.
4666723Sru&data_word(word)		Put in a word of data.
4768716Sru
4868716SruSo how does this all hold together?  Given
4917072Sjulian
5057676Ssheldonhint calc(int len, int *data)
5157676Ssheldonh	{
5217072Sjulian	int i,j=0;
5317072Sjulian
5417072Sjulian	for (i=0; i<len; i++)
5517072Sjulian		{
5617072Sjulian		j+=other(data[i]);
5717072Sjulian		}
5817072Sjulian	}
5917072Sjulian
6017072SjulianSo a very simple version of this function could be coded as
6117072Sjulian
6217072Sjulian	push(@INC,"perlasm","../../perlasm");
6317072Sjulian	require "x86asm.pl";
6417072Sjulian	
6592238Skeramida	&asm_init($ARGV[0],"cacl.pl");
6636679Sjulian
6717087Smpp	&external_label("other");
6817072Sjulian
6917072Sjulian	$tmp1=	"eax";
70117334Sdannyboy	$j=	"edi";
71117334Sdannyboy	$data=	"esi";
72117334Sdannyboy	$i=	"ebp";
73117334Sdannyboy
7417072Sjulian	&comment("a simple function");
7517072Sjulian	&function_begin("calc");
7617072Sjulian	&mov(	$data,		&wparam(1)); # data
77138968Sglebius	&xor(	$j,		$j);
7817072Sjulian	&xor(	$i,		$i);
79138968Sglebius
80138968Sglebius	&set_label("loop");
81138968Sglebius	&cmp(	$i,		&wparam(0));
82138968Sglebius	&jge(	&label("end"));
8317072Sjulian
8417072Sjulian	&mov(	$tmp1,		&DWP(0,$data,$i,4));
8517072Sjulian	&push(	$tmp1);
86117011Sru	&call(	"other");
87117011Sru	&add(	$j,		"eax");
8817072Sjulian	&pop(	$tmp1);
8917072Sjulian	&inc(	$i);
9017072Sjulian	&jmp(	&label("loop"));
9136364Sjulian
9236364Sjulian	&set_label("end");
9357676Ssheldonh	&mov(	"eax",		$j);
9457676Ssheldonh
9536364Sjulian	&function_end("calc");
9636364Sjulian
9781462Sru	&asm_finish();
98117011Sru
99117011SruThe above example is very very unoptimised but gives an idea of how
10017072Sjulianthings work.
10117072Sjulian
102117011SruThere is also a cbc mode function generator in cbc.pl
103117011Sru
10417072Sjulian&cbc(	$name,
10517072Sjulian	$encrypt_function_name,
10617072Sjulian	$decrypt_function_name,
10717072Sjulian	$true_if_byte_swap_needed,
10836679Sjulian	$parameter_number_for_iv,
10936679Sjulian	$parameter_number_for_encrypt_flag,
11036679Sjulian	$first_parameter_to_pass,
11166723Sru	$second_parameter_to_pass,
11257676Ssheldonh	$third_parameter_to_pass);
11357676Ssheldonh
11436679SjulianSo for example, given
11566723Sruvoid BF_encrypt(BF_LONG *data,BF_KEY *key);
11666723Sruvoid BF_decrypt(BF_LONG *data,BF_KEY *key);
11736679Sjulianvoid BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
11836679Sjulian        BF_KEY *ks, unsigned char *iv, int enc);
11917072Sjulian
12055807Sru&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
12181251Sru
12281251Sru&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
12355807Sru&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
12436679Sjulian
12536679Sjulian