#! /usr/bin/env perl
use
lib
"$FindBin::Bin/lib"
;
use
TestASM
qw( new_writer iterate_mem_addr_combos asm_ok @r64 @r32 @r16 @r8 @r8h @immed64 @immed32 @immed16 @immed8 )
;
subtest
call
=> \
&call
;
sub
call {
my
(
@asm
,
@out
);
push
@asm
,
"call label0\nnop\nlabel0: nop\n"
;
push
@out
, new_writer->call_label(
"label0"
)->nop->label(
"label0"
)->nop->bytes;
push
@asm
,
"label1: nop\nnop\nnop\ncall label1\n"
;
push
@out
, new_writer->label(
"label1"
)->nop(3)->call_label(
"label1"
)->bytes;
for
my
$reg
(
@r64
) {
push
@asm
,
"call $reg"
;
push
@out
, new_writer->call_abs_reg(
$reg
)->bytes;
}
iterate_mem_addr_combos(
\
@asm
,
sub
{
"call $_[0]"
},
\
@out
,
sub
{ new_writer->call_abs_mem([
@_
])->bytes }
);
asm_ok( \
@out
, \
@asm
,
'call'
);
}
subtest
ret
=> \
&ret
;
sub
ret {
my
(
@asm
,
@out
);
for
my
$bytes
(
''
, 1, 0x7F) {
push
@asm
,
"ret $bytes"
;
push
@out
, new_writer->ret(
$bytes
)->bytes;
}
asm_ok( \
@out
, \
@asm
,
'ret'
);
}
subtest
enter
=> \
&enter
;
sub
enter {
my
(
@asm
,
@out
);
for
my
$bytes
(
@immed16
) {
for
my
$nest
(0, 1, 8, 31) {
push
@asm
,
"enter $bytes, $nest"
;
push
@out
, new_writer->enter(
$bytes
,
$nest
)->bytes;
}
}
asm_ok( \
@out
, \
@asm
,
'enter'
);
}
subtest
leave
=> \
&leave
;
sub
leave {
my
(
@asm
,
@out
);
push
@asm
,
"leave"
;
push
@out
, new_writer->leave->bytes;
asm_ok( \
@out
, \
@asm
,
'leave'
);
}
subtest
push_
=> \
&push_
;
sub
push_ {
my
(
@asm
,
@out
);
for
my
$reg
(
@r64
) {
push
@asm
,
"push $reg"
;
push
@out
, new_writer->push_reg(
$reg
)->bytes;
}
for
my
$imm
(
@immed32
) {
push
@asm
,
"push qword $imm"
;
push
@out
, new_writer->push_imm(
$imm
)->bytes;
}
iterate_mem_addr_combos(
\
@asm
,
sub
{
"push qword $_[0]"
},
\
@out
,
sub
{ new_writer->push_mem([
@_
])->bytes }
);
asm_ok( \
@out
, \
@asm
,
'push'
);
}
subtest
pop_
=> \
&pop_
;
sub
pop_ {
my
(
@asm
,
@out
);
for
my
$reg
(
@r64
) {
push
@asm
,
"pop $reg"
;
push
@out
, new_writer->pop_reg(
$reg
)->bytes;
}
iterate_mem_addr_combos(
\
@asm
,
sub
{
"pop qword $_[0]"
},
\
@out
,
sub
{ new_writer->pop_mem([
@_
])->bytes }
);
asm_ok( \
@out
, \
@asm
,
'push'
);
}
done_testing;