Hi! I have a problem with the use of div in my assembly code and I’m trying to stablish what am I missing about the use of this instruction.
For the solution of a particular problem I decided to try out the “div” instruction. From what I’ve read, I worked under the assumption that “div rsi”, for instance, divides the value in rax by the value in rsi, storing the quotient in rax and the remainder in rdx. The experiments I’ve done on my machine (Fedora Linux, amd64 processor, nasm as the assembler) seems to corroborate that hypothesis.
However, running the code on the browser editor on my browser (I don’t know if it’s relevant, but I’m using Firefox) throws the error: “make: *** [Makefile:29: all] Arithmetic exception (core dumped)”. I’ve tried this operation with the sixteen general purpose registers, in case div was using an unitialized register as either the dividend or the divisor and that was causing the error, but it seems to have no effect.
Does someone know what the possible cause for this error might be? I’m new to x86-64 assembly, so I might have skipped some useful information in the documentation for this particular case.
Thanks in advance.
Is it possible you’re dividing by zero?
That is my hipothesis, too, which is why I tried storing an arbitrary integer number in different registers with an instruction similar to
mov rax, 3 to made sure that was not the case (I chose 3 to start with, for no particular reason). Not my most elegant decision ever, but I did try overwriting the registers from rax to r15 before calling div just in case.
I also tried specifying two registers for the instruction, which produced an error from the assembler which read “invalid combination of opcode and operands”, in conformity with the resources I have consulted.
The DIV instruction tripped me up too, and it might have been for the same reason. When given a 64-bit wide argument (say, RSI), DIV treats the combined contents of registers RDX:RAX as the dividend, and the argument register (RSI) as the divisor. There could be some residual value in RDX which turns the dividend into some gigantic 128-bit value, and if the resulting quotient overflows RAX, it will trigger a division error. Does it work if you clear RDX before performing the division?
The table at the bottom of this page in the Intel manual summarises the behaviour nicely:
Yes, clearing the rdx register does solve the problem and after that the program behaves correctly. Thank you very much!