Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

64bit nasm division idiv

;print out division message
mov rcx, 0                       ;zero out register
mov rax, [input]
mov rcx, [input2]
idiv rcx                        ;divide rax by rcx
mov rdi, rax                    ;for printing purposes
call print_int

I can't seem to figure out why this isn't dividing, I'm getting a enrror "Floating Point Exception" I'm using a 64bit machine and the values are integers not floating point.... ideas?

I know after the division takes place the quotient should be in rax, and the remainder should be in rdx i believe, but as of right now i'm just trying to get my hands on the quotient.

like image 840
user1050632 Avatar asked Dec 22 '22 03:12

user1050632


2 Answers

Your function looks a little bit complicated to me. idiv works as expected for me here with this function:

_mydiv:
  xor  %rdx, %rdx ; clear high bits of dividend
  mov  %rdi, %rax ; copy dividend argument into rax
  idiv %rsi       ; divide by divisor argument
  ret             ; return (quotient is in rax)

Translated into NASM syntax and to the windows ABI, I think that would be something like:

_mydiv:
  mov  r8, rdx    ; copy divisor argument to scratch register
  xor  rdx, rdx   ; clear high bits of dividend
  mov  rax, rcx   ; copy dividend argument into rax
  idiv r8         ; divide by divisor in scratch register
  ret             ; return (quotient is in rax)

Are you maybe stomping on your parameters and confusing something along the way?

Edit: looking at your code, it occurs to me that it might not be written as a proper function at all. The important steps are:

  1. Put dividend in RDX:RAX - for you that probably means clearing out RDX and putting the input dividend in RAX.
  2. Put divisor in some other register - you chose RCX, that should be fine.
  3. Divide - idiv rcx.
  4. Result will be in RAX.

You should pay particular attention to step 1 - make sure that RDX:RAX has sane contents! Why you're getting a floating point exception I can't guess from the code you've shown.

like image 172
Carl Norum Avatar answered Jan 05 '23 06:01

Carl Norum


You're actually dividing a 128-bit number in RDX:RAX by RCX. So if RDX is uninitialized the result will likely be larger than 64-bits, resulting in an overflow exception. Try adding a CQO before the division to sign-extend RAX into RDX.

I can't explain the floating-point bit though, maybe someone decided to reuse an interrupt vector for generic math errors somewhere down the line?

like image 39
doynax Avatar answered Jan 05 '23 06:01

doynax