1

Trying to divide a positive number by a negative number.

Currently my program will divide correctly, and I can correctly access the remainder.

But when I inputa positive number being divided by a negative value, it wont divide at all.

I know there is a way to "sign extend" and it will divide correctly. I just dont understand the manual

movsss $imm/%reg %reg/mem move, sign extend 231 movzss $imm/%reg %reg/mem move, zero extend

ofcourse thats att syntax, I need intel syntax

here is my code

xor rdx, rdx
mov rax, [input]
mov rcx, [input2]
idiv rcx

Ideas as how to divide by negative?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
user1050632
  • 680
  • 4
  • 13
  • 26
  • after doing some research I also found an instruction "cdq" that might do it, but hasn't worked yet – user1050632 Jan 31 '12 at 01:15
  • @SepRoland: lol, yes, apparently I hit return *before* control-v or something. – Peter Cordes Jun 04 '23 at 14:24
  • 1
    AT&T version of the same question: [X86 assembly - Handling the IDIV instruction](https://stackoverflow.com/q/10343155) (It forgets to handle RDX entirely, but the answers show the correct `ctqo` ; `idiv` for 64-bit signed division. – Peter Cordes Jun 04 '23 at 14:24

1 Answers1

6

If the divisor is a signed 64-bit value, you don't need to do anything with it. Likewise, if the dividend is a signed 128-bit value, you don't need to do anything with it, just load the top 64 bits of it into rdx and the low 64 bits into rax.

Now, if any of the numbers is signed but shorter than idiv expects, you need to sign-extend that number. Sign extension is very simple. You just fill the vacant top bits with the most significant bit (sign bit) of your number. For non-negative numbers you fill that space with 0's and for negative numbers you fill it with 1's. There are a few instructions available that can sign-extend the value currently held in the accumulator. They are: cbw, cwde, cdqe, cwd, cdq, cqo. The last three sign extend into dx/edx/rdx. Most likely you need cqo instead of xor rdx, rdx like this:

mov rax, [input]
cqo ; sign extends rax into rdx:rax
mov rcx, [input2]
idiv rcx

As for 'But when I inputa positive number being divided by a negative value, it wont divide at all', it can't be. It either divides or invokes a division exception (division by 0 or overflow), there's no third option.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • cqo worked!!!, i was trying cdq for a while and it didn't work, by chance can you point me to the source you used to figure that out? – user1050632 Jan 31 '12 at 01:18
  • In this document (from amd.com): AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions. – Alexey Frunze Jan 31 '12 at 01:43
  • @user1050632 Because there are already `cwd` (convert word to double word) and `cdq` (convert double to quad word) one can expect to find a 64 bit instruction like `cqo` (convert quad to oct word) or something similar named. – Gunther Piez Jan 31 '12 at 10:07