Blame crypto/perlasm/README

Packit c4476c
The perl scripts in this directory are my 'hack' to generate
Packit c4476c
multiple different assembler formats via the one original script.
Packit c4476c
Packit c4476c
The way to use this library is to start with adding the path to this directory
Packit c4476c
and then include it.
Packit c4476c
Packit c4476c
push(@INC,"perlasm","../../perlasm");
Packit c4476c
require "x86asm.pl";
Packit c4476c
Packit c4476c
The first thing we do is setup the file and type of assembler
Packit c4476c
Packit c4476c
&asm_init($ARGV[0]);
Packit c4476c
Packit c4476c
The first argument is the 'type'.  Currently
Packit c4476c
'cpp', 'sol', 'a.out', 'elf' or 'win32'.
Packit c4476c
Argument 2 is the file name.
Packit c4476c
Packit c4476c
The reciprocal function is
Packit c4476c
&asm_finish() which should be called at the end.
Packit c4476c
Packit c4476c
There are 2 main 'packages'. x86ms.pl, which is the Microsoft assembler,
Packit c4476c
and x86unix.pl which is the unix (gas) version.
Packit c4476c
Packit c4476c
Functions of interest are:
Packit c4476c
&external_label("des_SPtrans");	declare and external variable
Packit c4476c
&LB(reg);			Low byte for a register
Packit c4476c
&HB(reg);			High byte for a register
Packit c4476c
&BP(off,base,index,scale)	Byte pointer addressing
Packit c4476c
&DWP(off,base,index,scale)	Word pointer addressing
Packit c4476c
&stack_push(num)		Basically a 'sub esp, num*4' with extra
Packit c4476c
&stack_pop(num)			inverse of stack_push
Packit c4476c
&function_begin(name,extra)	Start a function with pushing of
Packit c4476c
				edi, esi, ebx and ebp.  extra is extra win32
Packit c4476c
				external info that may be required.
Packit c4476c
&function_begin_B(name,extra)	Same as normal function_begin but no pushing.
Packit c4476c
&function_end(name)		Call at end of function.
Packit c4476c
&function_end_A(name)		Standard pop and ret, for use inside functions
Packit c4476c
&function_end_B(name)		Call at end but with pop or ret.
Packit c4476c
&swtmp(num)			Address on stack temp word.
Packit c4476c
&wparam(num)			Parameter number num, that was push
Packit c4476c
				in C convention.  This all works over pushes
Packit c4476c
				and pops.
Packit c4476c
&comment("hello there")		Put in a comment.
Packit c4476c
&label("loop")			Refer to a label, normally a jmp target.
Packit c4476c
&set_label("loop")		Set a label at this point.
Packit c4476c
&data_word(word)		Put in a word of data.
Packit c4476c
Packit c4476c
So how does this all hold together?  Given
Packit c4476c
Packit c4476c
int calc(int len, int *data)
Packit c4476c
	{
Packit c4476c
	int i,j=0;
Packit c4476c
Packit c4476c
	for (i=0; i
Packit c4476c
		{
Packit c4476c
		j+=other(data[i]);
Packit c4476c
		}
Packit c4476c
	}
Packit c4476c
Packit c4476c
So a very simple version of this function could be coded as
Packit c4476c
Packit c4476c
	push(@INC,"perlasm","../../perlasm");
Packit c4476c
	require "x86asm.pl";
Packit c4476c
	
Packit c4476c
	&asm_init($ARGV[0]);
Packit c4476c
Packit c4476c
	&external_label("other");
Packit c4476c
Packit c4476c
	$tmp1=	"eax";
Packit c4476c
	$j=	"edi";
Packit c4476c
	$data=	"esi";
Packit c4476c
	$i=	"ebp";
Packit c4476c
Packit c4476c
	&comment("a simple function");
Packit c4476c
	&function_begin("calc");
Packit c4476c
	&mov(	$data,		&wparam(1)); # data
Packit c4476c
	&xor(	$j,		$j);
Packit c4476c
	&xor(	$i,		$i);
Packit c4476c
Packit c4476c
	&set_label("loop");
Packit c4476c
	&cmp(	$i,		&wparam(0));
Packit c4476c
	&jge(	&label("end"));
Packit c4476c
Packit c4476c
	&mov(	$tmp1,		&DWP(0,$data,$i,4));
Packit c4476c
	&push(	$tmp1);
Packit c4476c
	&call(	"other");
Packit c4476c
	&add(	$j,		"eax");
Packit c4476c
	&pop(	$tmp1);
Packit c4476c
	&inc(	$i);
Packit c4476c
	&jmp(	&label("loop"));
Packit c4476c
Packit c4476c
	&set_label("end");
Packit c4476c
	&mov(	"eax",		$j);
Packit c4476c
Packit c4476c
	&function_end("calc");
Packit c4476c
Packit c4476c
	&asm_finish();
Packit c4476c
Packit c4476c
The above example is very very unoptimised but gives an idea of how
Packit c4476c
things work.
Packit c4476c
Packit c4476c
There is also a cbc mode function generator in cbc.pl
Packit c4476c
Packit c4476c
&cbc(	$name,
Packit c4476c
	$encrypt_function_name,
Packit c4476c
	$decrypt_function_name,
Packit c4476c
	$true_if_byte_swap_needed,
Packit c4476c
	$parameter_number_for_iv,
Packit c4476c
	$parameter_number_for_encrypt_flag,
Packit c4476c
	$first_parameter_to_pass,
Packit c4476c
	$second_parameter_to_pass,
Packit c4476c
	$third_parameter_to_pass);
Packit c4476c
Packit c4476c
So for example, given
Packit c4476c
void BF_encrypt(BF_LONG *data,BF_KEY *key);
Packit c4476c
void BF_decrypt(BF_LONG *data,BF_KEY *key);
Packit c4476c
void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
Packit c4476c
        BF_KEY *ks, unsigned char *iv, int enc);
Packit c4476c
Packit c4476c
&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
Packit c4476c
Packit c4476c
&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
Packit c4476c
&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
Packit c4476c