ヒントありがとうございます。おかげさまで謎が解けました。
subルーチン内では特殊変数$_ではなく配列にコピーされるんですね。

#!/usr/bin/perl

$ans = func(5);
print $ans; #5×4×3×2×1

sub func()
{
(my $n) = $_[0];
if($n == 1){
return 1;
}
else{
return $n * func($n-1);
}
}

exit;