Apress / low-level-programming

Source code for 'Low-Level Programming' by Igor Zhirkov
http://www.apress.com/9781484224021
Other
768 stars 200 forks source link

Q40 #63

Closed Anding closed 6 years ago

Anding commented 6 years ago
label:
neg rax
jl label
; here rax holds its absolute value

jl responds to SF != OF. js seems to work as well and is a "logical" choice.

Is jl preferred for any reason?

sayon commented 6 years ago

Thank you for a wonderful question!

Usually, js will do the trick except for one case: if rax is equal to the smallest signed integer. It is because the range of 64-bit integers is asymmetric: -2^64 ... 2^64 - 1. When rax is the smallest negative integer, its 2 complement (computed by neg) is the same and as the result we get stuck in a loop. Let's study these two examples:

Normal case: rax = -10

label:      ; rax = -10
neg rax  ; rax = 10, CF, PF, AF set
js label   ;  OK, no jump

Corner case: rax = -2^64 = 0x80 00 00 00 00 00 00 00

label:      ; rax = -2^64
neg rax  ; rax = -2^64, CF, PF, SF, OF  are set
js label   ;  `rax` is still negative and won't change its sign. 

Now we are stuck performing neg (which has no effect) and js till the end of the world. However, notice, that both SF and OF are set in this case. This is the exact situation when jl will prevent us from being stuck in a loop.