5
;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.

user1050632
  • 680
  • 4
  • 13
  • 26

2 Answers2

10

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.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
2

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?

doynax
  • 4,285
  • 3
  • 23
  • 19
  • For future reference, where does one find instructions like `cqo`? In GAS syntax, it's `cqto`, and it doesn't seem clear what it should convert to in MASM syntax. – Vortico Jan 11 '14 at 00:39
  • @Vortico: [The Intel Architecture Manuals](http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html) are always a good start. As for CQO specifically I confess I didn't know the proper suffix for a 128-bit word but had to look up CBW/CWD/CDQ to see what the 64-bit equivalent might be called – doynax Jan 11 '14 at 01:04