Andy Polyakov a9e790b95a perlasm/x86_64-xlate.pl: extend SSE>2 to ml64. 14 år sedan
..
cbc.pl e19e549041 Comply with optimization manual (no data should share cache-line with code). 19 år sedan
ppc-xlate.pl 7676eebf42 OPENSSL_cleanse to accept zero length parameter [matching C implementation]. 15 år sedan
readme 58964a4922 Import of old SSLeay release: SSLeay 0.9.0b 26 år sedan
x86_64-xlate.pl a9e790b95a perlasm/x86_64-xlate.pl: extend SSE>2 to ml64. 14 år sedan
x86asm.pl 133a7f9a50 perlasm/x86asm.pl: move aesni and pclmulqdq opcodes to aesni-x86.pl and 14 år sedan
x86gas.pl d08eae1bda x86 perlasm: add support for 16-bit values. 14 år sedan
x86masm.pl d08eae1bda x86 perlasm: add support for 16-bit values. 14 år sedan
x86nasm.pl d08eae1bda x86 perlasm: add support for 16-bit values. 14 år sedan

readme

The perl scripts in this directory are my 'hack' to generate
multiple different assembler formats via the one origional script.

The way to use this library is to start with adding the path to this directory
and then include it.

push(@INC,"perlasm","../../perlasm");
require "x86asm.pl";

The first thing we do is setup the file and type of assember

&asm_init($ARGV[0],$0);

The first argument is the 'type'. Currently
'cpp', 'sol', 'a.out', 'elf' or 'win32'.
Argument 2 is the file name.

The reciprocal function is
&asm_finish() which should be called at the end.

There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
and x86unix.pl which is the unix (gas) version.

Functions of interest are:
&external_label("des_SPtrans"); declare and external variable
&LB(reg); Low byte for a register
&HB(reg); High byte for a register
&BP(off,base,index,scale) Byte pointer addressing
&DWP(off,base,index,scale) Word pointer addressing
&stack_push(num) Basically a 'sub esp, num*4' with extra
&stack_pop(num) inverse of stack_push
&function_begin(name,extra) Start a function with pushing of
edi, esi, ebx and ebp. extra is extra win32
external info that may be required.
&function_begin_B(name,extra) Same as norma function_begin but no pushing.
&function_end(name) Call at end of function.
&function_end_A(name) Standard pop and ret, for use inside functions
&function_end_B(name) Call at end but with poping or 'ret'.
&swtmp(num) Address on stack temp word.
&wparam(num) Parameter number num, that was push
in C convention. This all works over pushes
and pops.
&comment("hello there") Put in a comment.
&label("loop") Refer to a label, normally a jmp target.
&set_label("loop") Set a label at this point.
&data_word(word) Put in a word of data.

So how does this all hold together? Given

int calc(int len, int *data)
{
int i,j=0;

for (i=0; i {
j+=other(data[i]);
}
}

So a very simple version of this function could be coded as

push(@INC,"perlasm","../../perlasm");
require "x86asm.pl";

&asm_init($ARGV[0],"cacl.pl");

&external_label("other");

$tmp1= "eax";
$j= "edi";
$data= "esi";
$i= "ebp";

&comment("a simple function");
&function_begin("calc");
&mov( $data, &wparam(1)); # data
&xor( $j, $j);
&xor( $i, $i);

&set_label("loop");
&cmp( $i, &wparam(0));
&jge( &label("end"));

&mov( $tmp1, &DWP(0,$data,$i,4));
&push( $tmp1);
&call( "other");
&add( $j, "eax");
&pop( $tmp1);
&inc( $i);
&jmp( &label("loop"));

&set_label("end");
&mov( "eax", $j);

&function_end("calc");

&asm_finish();

The above example is very very unoptimised but gives an idea of how
things work.

There is also a cbc mode function generator in cbc.pl

&cbc( $name,
$encrypt_function_name,
$decrypt_function_name,
$true_if_byte_swap_needed,
$parameter_number_for_iv,
$parameter_number_for_encrypt_flag,
$first_parameter_to_pass,
$second_parameter_to_pass,
$third_parameter_to_pass);

So for example, given
void BF_encrypt(BF_LONG *data,BF_KEY *key);
void BF_decrypt(BF_LONG *data,BF_KEY *key);
void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *ks, unsigned char *iv, int enc);

&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);

&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);