7
votes

I am learning about division in assembly language. According to the book I am learning from, the result of the idiv operation is placed in eax and the remainder in edx.

An exercise in the book is to implement number = result % divisor in assembly.

I would have thought this would be equivalent to a normal divide operation except edx would be the result.

This did not work however and edx returned seemingly garbage.

Why? How do you implemented the above pseudo-code in assembly?

1
I would code a tiny C function, and look at the generated assembly (e.g. with gcc -O -fverbose-asm -S tiny.c) - Basile Starynkevitch
Your question is similar to stackoverflow.com/questions/8021772/… Show your actual code if you're having specific problems (most likely you're not clearing the upper upper part of rdx:rax, edx:eax or dx:ax). - user786653
Hard to guess without seeing code, but one common slip-up is forgetting to zero edx before the idiv. - Jerry Coffin

1 Answers

20
votes

Integer modulo can be implemented in two ways:

Firstly by using DIV or IDIV, where the remainder will be put into EDX, but you need to zero EDX first, or to quote intel:

Operand Size -----------| Dividend | Divisor | Quotient | Remainder
Quadword/doubleword     | EDX:EAX  |  r/m32  |   EAX    |   EDX. 

eg:

eax = eax % 9

when unsigned becomes:

XOR EDX,EDX ;clear the destinations for outputs. this stops the garbage remainder  
MOV ECX,9
DIV ECX
MOV EAX,EDX

when signed, it is:

MOV ECX,9
CDQ ;this will clear EDX due to the sign extension
IDIV ECX
MOV EAX,EDX

The second way is an optimization used when you modulo using a power of two, in this case you AND by one less than the power of two, eg: eax = eax % 8 becomes AND EAX,7.