Some instructions act on registers or even memory locations that are not stated in a list of operands. These instruction does do in fact have operands, but they represent assumptions made by the instruction. Implicit operands dose not change and cannot be changed. Most of the instruction that have implicit opeands dose have explicit operands as well.
The MUL instruction multiplies two values and returns the product. However, multiplication has a special problem: It generates output values that are often hugely lager than the input values. think of 0xffffffff * 0xffffffff.
So to solve this problem the MUL instructison uses an implicit operands to store the product: by using two registers to hold our product.
Note
The implicit operands for MUL instruction depend on the explicit operand (size)
| Instruction | Explicit operand (a.k.a. factor 1) | Implicit operand (a.k.a factor 2) | Implicit operand (a.k.a product) |
|---|---|---|---|
| MUL r/m8 | r/m8 | AL | AX |
| MUL r/m16 | r/m16 | AX | DX:AX |
| MUL r/m32 | r/m32 | EAX | EDX:EAX |
| MUL r/m64 | r/m64 | RAX | RDX:RAX |
The first factor is given in the single explicit operand, which can be either in a register or in a memory location. The second foctor is implicit and always in the
Ageneral-purpose register appropriate to the size of the first operand.
Note
DX registers are drafted to hold the high-ordr portion of the product.
I.e. if you multiply two 16-bit values and the product is 0x2A46FH, register AX will contain 0x456FH, and DX will contain 0x2AH.
Note
Even in cases when the product is small enough to fit in entirely in the first emplicit operand(A GPR), the high-orrder register whether AH, DX, EDX, or RDX) is zerod out. So you can't use them even if you'r sure that MUL instruction will not need them.
mov bl, 21
mov al, 2
mul bl ; al = 0x2aNote
You cannot use the immediate vales as an operand.
The MUL instruction will sets the Carry flag CF when the value of the product overflowss the low-order register.so you can ignore the high-order register when CF isn't set.
mov eax, 0ffff_ffffh
mov ebx, 03b72h
mul ebx ; OF will setThe DIV instruction divides one unsigned value by another and gives you a quotient and a remainder.
In division, you don't have the problem that multiplication has, of generating largo output value. However, it would be useful to be able to divide very large numbers, so we use the same trick as MUL but in reverse.
| Instruction | Explicit operand(a.k.a. Divisor) | Implicit operand(a.k.a. Dividend) | Result(Quotient) | Result(Remainder) |
|---|---|---|---|---|
| DIV r/m8 | r/m8 | AX | AL | AH |
| DIV r/m16 | r/m16 | DX:AX | AX | DX |
| DIV r/m32 | r/m32 | EDX:EAX | EAX | EDX |
| DIV r/m64 | r/m64 | RDX:RAX | RAX | RDX |
Note
DIV instruction dose not place any useful data in any of the flags. And it will leave OF, SF, ZF, AF , PF, AND CF in undifined statate.
mov rax, 327
mov rbx, 2
div rbx ; sets RAX to 0xA3, and RDX to 0x1Warning
If you endup divideng by zero, the kernel will send a SIGFPE signel to your process and termnate it.
mov rax, 525
mov rbx, 0
mul rbx