1The perl scripts in this directory are my 'hack' to generate 2multiple different assembler formats via the one origional script. 3 4The way to use this library is to start with adding the path to this directory 5and then include it. 6 7push(@INC,"perlasm","../../perlasm"); 8require "x86asm.pl"; 9 10The first thing we do is setup the file and type of assembler 11 12&asm_init($ARGV[0],$0); 13 14The first argument is the 'type'. Currently 15'cpp', 'sol', 'a.out', 'elf' or 'win32'. 16Argument 2 is the file name. 17 18The reciprocal function is 19&asm_finish() which should be called at the end. 20 21There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler, 22and x86unix.pl which is the unix (gas) version. 23 24Functions of interest are: 25&external_label("des_SPtrans"); declare and external variable 26&LB(reg); Low byte for a register 27&HB(reg); High byte for a register 28&BP(off,base,index,scale) Byte pointer addressing 29&DWP(off,base,index,scale) Word pointer addressing 30&stack_push(num) Basically a 'sub esp, num*4' with extra 31&stack_pop(num) inverse of stack_push 32&function_begin(name,extra) Start a function with pushing of 33 edi, esi, ebx and ebp. extra is extra win32 34 external info that may be required. 35&function_begin_B(name,extra) Same as norma function_begin but no pushing. 36&function_end(name) Call at end of function. 37&function_end_A(name) Standard pop and ret, for use inside functions 38&function_end_B(name) Call at end but with poping or 'ret'. 39&swtmp(num) Address on stack temp word. 40&wparam(num) Parameter number num, that was push 41 in C convention. This all works over pushes 42 and pops. 43&comment("hello there") Put in a comment. 44&label("loop") Refer to a label, normally a jmp target. 45&set_label("loop") Set a label at this point. 46&data_word(word) Put in a word of data. 47 48So how does this all hold together? Given 49 50int calc(int len, int *data) 51 { 52 int i,j=0; 53 54 for (i=0; i<len; i++) 55 { 56 j+=other(data[i]); 57 } 58 } 59 60So a very simple version of this function could be coded as 61 62 push(@INC,"perlasm","../../perlasm"); 63 require "x86asm.pl"; 64 65 &asm_init($ARGV[0],"cacl.pl"); 66 67 &external_label("other"); 68 69 $tmp1= "eax"; 70 $j= "edi"; 71 $data= "esi"; 72 $i= "ebp"; 73 74 &comment("a simple function"); 75 &function_begin("calc"); 76 &mov( $data, &wparam(1)); # data 77 &xor( $j, $j); 78 &xor( $i, $i); 79 80 &set_label("loop"); 81 &cmp( $i, &wparam(0)); 82 &jge( &label("end")); 83 84 &mov( $tmp1, &DWP(0,$data,$i,4)); 85 &push( $tmp1); 86 &call( "other"); 87 &add( $j, "eax"); 88 &pop( $tmp1); 89 &inc( $i); 90 &jmp( &label("loop")); 91 92 &set_label("end"); 93 &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