Obsess over every detail. Ask why it works. Ask why it isn’t built another way.

Multiplication and Division in Assembly

C code:

1
2
3
4
5
6
7
#define uint64 unsigned long long
uint64 main(){
    uint64 a = 0xdefec7ed;
    a *= 0xde7ec7ab1e;
    a /= 0x2bad505ad;
    return a;
}

Dissassembled;

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
uint32_t main()
    push    rbp
    mov     rbp, rsp
    sub     rsp, 0x40
    call    __main
    mov     eax, 0xdefec7ed
    mov     qword [rbp-0x8], rax
    mov     rax, 0xde7ec7ab1e
    mov     qword [rbp-0x10], rax
    mov     rax, 0x2bad505ad
    mov     qword [rbp-0x18], rax
    mov     rax, qword [rbp-0x8]
    imul    rax, qword [rbp-0x10]
    mov     qword [rbp-0x8], rax
    mov     rcx, qword [rbp-0x18]
    mov     rax, qword [rbp-0x8]
    mov     edx, 0
    div     rcx ; new instruction
    mov     qword [rbp-0x8], rax
    mov     rax, qword [rbp-0x8]
    add     rsp, 0x40
    pop     rbp
    ret

DIV - Unsigned divide

Three forms:

If dividend is 32/64 bits, edx/rdx will just be set to 0 by the compiler before the instruction.

If the divisor is 0, a divide by zero exception is raised!

Example 1

Initial state:

+-----+-----------+
| ax  | r/m8 (cx) |
+-----+-----------+
| 0x8 | 0x3       |
+-----+-----------+

Operation: div cx

After:

+-----+-----------+
| ah  | al        |
+-----+-----------+
| 0x2 | 0x2       |
+-----+-----------+

Example 2

Initial state:

+-----+-----+-----------+
| rdx | rax | r/m64(rcx)|
+-----+-----+-----------+
| 0x0 | 0x8 | 0x5       |
+-----+-----+-----------+

Operation: div rcx

After:

+-----+-----+-----------+
| rdx | rax | r/m64(rcx)|
+-----+-----+-----------+
| 0x3 | 0x1 | 0x5       |
+-----+-----+-----------+

IDIV - Signed divide

Three forms:

If dividend is 32/64 bits, edx/rdx will just be set to 0 by the compiler before the instruction. If the divisor is 0, a divide by zero exception is raised!

Example 1

Initial state:

+------+-----------+
| ax   | r/m8 (cx) |
+------+-----------+
| 0xFE | 0x2       |
+------+-----------+

Operation: idiv cx

After:

+-----+-----------+
| ah  | al        |
+-----+-----------+
| 0x0 | 0xFF      |
+-----+-----------+

Example 2

Initial state:

+-----+----------+-----------+
| rdx | rax      | r/m64(rcx)|
+-----+----------+-----------+
| 0x0 | 0x57e11a | 0xb01d    |
+-----+----------+-----------+

Operation: idiv rcx

After:

+--------+-----+-----------+
| rdx    | rax | r/m64(rcx)|
+--------+-----+-----------+
| 0x82B7 | 0x7F| 0xb01d    |
+--------+-----+-----------+