1Perl scripts for assembler sources 2================================== 3 4The perl scripts in this directory are my 'hack' to generate 5multiple different assembler formats via the one original script. 6 7The way to use this library is to start with adding the path to this directory 8and then include it. 9 10 push(@INC,"perlasm","../../perlasm"); 11 require "x86asm.pl"; 12 13The first thing we do is setup the file and type of assembler 14 15 &asm_init($ARGV[0]); 16 17The first argument is the 'type'. Currently 18`cpp`, `sol`, `a.out`, `elf` or `win32`. 19The second argument is the file name. 20 21The reciprocal function is 22`&asm_finish()` which should be called at the end. 23 24There are two main 'packages'. `x86ms.pl`, which is the Microsoft assembler, 25and `x86unix.pl` which is the unix (gas) version. 26 27Functions of interest are: 28 29 &external_label("des_SPtrans"); declare and external variable 30 &LB(reg); Low byte for a register 31 &HB(reg); High byte for a register 32 &BP(off,base,index,scale) Byte pointer addressing 33 &DWP(off,base,index,scale) Word pointer addressing 34 &stack_push(num) Basically a 'sub esp, num*4' with extra 35 &stack_pop(num) inverse of stack_push 36 &function_begin(name,extra) Start a function with pushing of 37 edi, esi, ebx and ebp. extra is extra win32 38 external info that may be required. 39 &function_begin_B(name,extra) Same as normal function_begin but no 40 pushing. 41 &function_end(name) Call at end of function. 42 &function_end_A(name) Standard pop and ret, for use inside 43 functions. 44 &function_end_B(name) Call at end but with pop or ret. 45 &swtmp(num) Address on stack temp word. 46 &wparam(num) Parameter number num, that was push in 47 C convention. This all works over pushes 48 and pops. 49 &comment("hello there") Put in a comment. 50 &label("loop") Refer to a label, normally a jmp target. 51 &set_label("loop") Set a label at this point. 52 &data_word(word) Put in a word of data. 53 54So how does this all hold together? Given 55 56 int calc(int len, int *data) 57 { 58 int i,j=0; 59 60 for (i=0; i<len; i++) 61 { 62 j+=other(data[i]); 63 } 64 } 65 66So a very simple version of this function could be coded as 67 68 push(@INC,"perlasm","../../perlasm"); 69 require "x86asm.pl"; 70 71 &asm_init($ARGV[0]); 72 73 &external_label("other"); 74 75 $tmp1= "eax"; 76 $j= "edi"; 77 $data= "esi"; 78 $i= "ebp"; 79 80 &comment("a simple function"); 81 &function_begin("calc"); 82 &mov( $data, &wparam(1)); # data 83 &xor( $j, $j); 84 &xor( $i, $i); 85 86 &set_label("loop"); 87 &cmp( $i, &wparam(0)); 88 &jge( &label("end")); 89 90 &mov( $tmp1, &DWP(0,$data,$i,4)); 91 &push( $tmp1); 92 &call( "other"); 93 &add( $j, "eax"); 94 &pop( $tmp1); 95 &inc( $i); 96 &jmp( &label("loop")); 97 98 &set_label("end"); 99 &mov( "eax", $j); 100 101 &function_end("calc"); 102 103 &asm_finish(); 104 105The above example is very very unoptimised but gives an idea of how 106things work. 107 108There is also a cbc mode function generator in cbc.pl 109 110 &cbc($name, 111 $encrypt_function_name, 112 $decrypt_function_name, 113 $true_if_byte_swap_needed, 114 $parameter_number_for_iv, 115 $parameter_number_for_encrypt_flag, 116 $first_parameter_to_pass, 117 $second_parameter_to_pass, 118 $third_parameter_to_pass); 119 120So for example, given 121 122 void BF_encrypt(BF_LONG *data,BF_KEY *key); 123 void BF_decrypt(BF_LONG *data,BF_KEY *key); 124 void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length, 125 BF_KEY *ks, unsigned char *iv, int enc); 126 127 &cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1); 128 129 &cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1); 130 &cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5); 131