Exponentiation by squaring in x64 Linux Assembly
Testing for n == 1 before handling a negative n seems like a bug. Consider what would have happen with n == -1:

n is not 1. Branch to _notEqualsOne.
n is less than 0. Branch to _lessthan. Now n becomes 1.
The code falls through all the way to _loop1.
n is odd. Branch to _odd.
y := x * y; x := x * x; n := 0`
_condition fails; fall through the return x * y.

Now, this is bad: we are returning an inversed cube of the original x.
Postpone equality for 1 testing until the negative case is handled.

Eliminate _equalsOne label:
  cmp r9, 1
  jne _notEqualsOne

  mov rax, r8
  ret

_notEqualsOne:


cmp r9, 0 is executed twice. This is redundant (keep in mind that jne does not affect the flags):
  cmp r9, 0
  jne _notZero
  ; next two lines is what your code does at _ezero
  mov rax, 1
  ret

_notZero:
  jnl _positive
  ; handle a negative case here:
  ; x := 1/x
  ; n := -n
  ; and proceed with the _positive case
  ....

_positive:
  ; A regular case. n &gt; 1 is guaranteed.


Again, _even and _odd lead to some code duplication.  x := x * x and n := n/2 are spelled out in both branches. Consider
  test al, 1
  jz _even

  ; n is odd here
  ; y := x * y
  ; n := n - 1

_even:
  ; x := x * x
  ; n := n / 2


Division by 2 is better be a right shift. One instruction versus four; a definite win.

while n &gt; 1 style loop looks more natural than do ... while n &gt; 1.