101 lines
2.6 KiB
Plaintext
101 lines
2.6 KiB
Plaintext
|
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 assembler
|
||
|
|
||
|
&asm_init($ARGV[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 normal 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<len; 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]);
|
||
|
|
||
|
&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.
|