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