1234949SbaptThe perl scripts in this directory are my 'hack' to generate 2234949Sbaptmultiple different assembler formats via the one origional script. 3234949Sbapt 4234949SbaptThe way to use this library is to start with adding the path to this directory 5234949Sbaptand then include it. 6234949Sbapt 7234949Sbaptpush(@INC,"perlasm","../../perlasm"); 8234949Sbaptrequire "x86asm.pl"; 9234949Sbapt 10234949SbaptThe first thing we do is setup the file and type of assember 11234949Sbapt 12234949Sbapt&asm_init($ARGV[0],$0); 13234949Sbapt 14234949SbaptThe first argument is the 'type'. Currently 15234949Sbapt'cpp', 'sol', 'a.out', 'elf' or 'win32'. 16234949SbaptArgument 2 is the file name. 17234949Sbapt 18234949SbaptThe reciprocal function is 19234949Sbapt&asm_finish() which should be called at the end. 20234949Sbapt 21234949SbaptThere are 2 main 'packages'. x86ms.pl, which is the microsoft assembler, 22234949Sbaptand x86unix.pl which is the unix (gas) version. 23234949Sbapt 24234949SbaptFunctions of interest are: 25234949Sbapt&external_label("des_SPtrans"); declare and external variable 26234949Sbapt&LB(reg); Low byte for a register 27234949Sbapt&HB(reg); High byte for a register 28234949Sbapt&BP(off,base,index,scale) Byte pointer addressing 29234949Sbapt&DWP(off,base,index,scale) Word pointer addressing 30234949Sbapt&stack_push(num) Basically a 'sub esp, num*4' with extra 31234949Sbapt&stack_pop(num) inverse of stack_push 32234949Sbapt&function_begin(name,extra) Start a function with pushing of 33234949Sbapt edi, esi, ebx and ebp. extra is extra win32 34234949Sbapt external info that may be required. 35234949Sbapt&function_begin_B(name,extra) Same as norma function_begin but no pushing. 36234949Sbapt&function_end(name) Call at end of function. 37234949Sbapt&function_end_A(name) Standard pop and ret, for use inside functions 38234949Sbapt&function_end_B(name) Call at end but with poping or 'ret'. 39234949Sbapt&swtmp(num) Address on stack temp word. 40234949Sbapt&wparam(num) Parameter number num, that was push 41234949Sbapt in C convention. This all works over pushes 42234949Sbapt and pops. 43234949Sbapt&comment("hello there") Put in a comment. 44234949Sbapt&label("loop") Refer to a label, normally a jmp target. 45234949Sbapt&set_label("loop") Set a label at this point. 46234949Sbapt&data_word(word) Put in a word of data. 47234949Sbapt 48234949SbaptSo how does this all hold together? Given 49234949Sbapt 50234949Sbaptint calc(int len, int *data) 51234949Sbapt { 52234949Sbapt int i,j=0; 53234949Sbapt 54234949Sbapt for (i=0; i<len; i++) 55234949Sbapt { 56234949Sbapt j+=other(data[i]); 57234949Sbapt } 58234949Sbapt } 59234949Sbapt 60234949SbaptSo a very simple version of this function could be coded as 61234949Sbapt 62234949Sbapt push(@INC,"perlasm","../../perlasm"); 63234949Sbapt require "x86asm.pl"; 64234949Sbapt 65234949Sbapt &asm_init($ARGV[0],"cacl.pl"); 66234949Sbapt 67234949Sbapt &external_label("other"); 68234949Sbapt 69234949Sbapt $tmp1= "eax"; 70234949Sbapt $j= "edi"; 71234949Sbapt $data= "esi"; 72234949Sbapt $i= "ebp"; 73234949Sbapt 74234949Sbapt &comment("a simple function"); 75234949Sbapt &function_begin("calc"); 76234949Sbapt &mov( $data, &wparam(1)); # data 77234949Sbapt &xor( $j, $j); 78234949Sbapt &xor( $i, $i); 79234949Sbapt 80234949Sbapt &set_label("loop"); 81234949Sbapt &cmp( $i, &wparam(0)); 82234949Sbapt &jge( &label("end")); 83234949Sbapt 84234949Sbapt &mov( $tmp1, &DWP(0,$data,$i,4)); 85234949Sbapt &push( $tmp1); 86234949Sbapt &call( "other"); 87234949Sbapt &add( $j, "eax"); 88234949Sbapt &pop( $tmp1); 89234949Sbapt &inc( $i); 90234949Sbapt &jmp( &label("loop")); 91234949Sbapt 92234949Sbapt &set_label("end"); 93234949Sbapt &mov( "eax", $j); 94 95 &function_end("calc"); 96 97 &asm_finish(); 98 99The above example is very very unoptimised but gives an idea of how 100things work. 101 102There is also a cbc mode function generator in cbc.pl 103 104&cbc( $name, 105 $encrypt_function_name, 106 $decrypt_function_name, 107 $true_if_byte_swap_needed, 108 $parameter_number_for_iv, 109 $parameter_number_for_encrypt_flag, 110 $first_parameter_to_pass, 111 $second_parameter_to_pass, 112 $third_parameter_to_pass); 113 114So for example, given 115void BF_encrypt(BF_LONG *data,BF_KEY *key); 116void BF_decrypt(BF_LONG *data,BF_KEY *key); 117void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length, 118 BF_KEY *ks, unsigned char *iv, int enc); 119 120&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1); 121 122&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1); 123&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5); 124 125