This blog was last modified 428 days before.
Logical Calculation
CMP, AND, TEST, OR, XOR, NOT.
These are logical operaion instructions on CPU 8086. They just do the thing that what they called, try these out by yourself on simulator.
ADD, SUB, MUL, IMUL, DIV, IDIV, NEG
These are arithmetical operation.
CMP and Lexical Flag Analyze
We could think that CMP
instruction is actually using SUB
to subtract one number from another number, but only update the flags and do not store the result.
For example:
mov ax, 1
mov bx, 2
sub ax, bx
mov ax, 1
mov bx, 2
cmp ax, bx
Run these two different code, you would got the same flags status. But in the first case you got an -1
in ax
, but in the second cases the value of ax
is still 1
.
Try these out on your own.
Where's the result?
As we said above, the CMP
instruction do NOT store the result, then how can we know the result of this CMP
instruction? The answer is through those tiny flags.
I would give the conclusion first: In case of running instruction cmp ax, bx
-
OF == SF
=>[ax] >= [bx]
-
OF <> SF
=>[ax] <= [bx]
Note:
<>
meansnot equal
here.
Why?
Let's discuss the situation.
(1) When OF == 0
Since no overflow occured, we could know that:
-
SF == 0
=>ax - bx >= 0
=>ax >= bx
-
SF == 1
=>ax - bx <= 0
=>ax <= bx
(2) When OF == 1
There are two types of overflow:
- Upper Bound Overflow:
ax >= 0
andbx <= 0
=>ax >= bx
- Lower Bound Overflow:
ax <= 0
andbx >= 0
=>ax <= bx
And:
- When Upper Bound Overflow occured,
SF
should be1
, since the result cross the upper bound and goes in to the range of the negatives. - When Lower Bound Overflow occured,
SF
should be0
, since the result cross the lower bound and goes in to the range of the positives.
Then we have:
-
SF == 1
=>ax >= bx
-
SF == 0
=>ax <= bx
Finally we have:
OF | SF | REL |
---|---|---|
0 | 0 | >= |
0 | 1 | <= |
1 | 0 | <= |
1 | 1 | >= |
That's what is given at fisrt:
-
OF == SF
=>[ax] >= [bx]
-
OF <> SF
=>[ax] <= [bx]
Arithmetic Operation
Most of the arithmetic operation instruction just do as what they called. ADD
do addition, MUL
do multiplication etc.
-
IMUL
andIDIV
means doing multiplication/division but with the consideration of the sign.
MUL / IMUL Carry
; arithmetic calculation test
; add
mov ax, un_word_max
mov bx, un_word_max
add ax, bx
; usigned mul (byte) carry
mov al, un_byte_max
mov bl, 2
mul bl
; unsigned mul carry
mov ax, un_word_max
mul bx
; result stored in H:dx L:ax
; signed imul overflow
mov ax, sg_word_max
mov bx, 2
imul bx
; idiv test
mov ax, 3
mov bx, -1
idiv bx
ret
un_word_max dw 0ffffh
sg_word_max dw 07fffh
un_byte_max db 0ffh
sg_byte_max db 07fh
Here notice that AX
is default register used when using instruction MUL
, IMUL
, DIV
, IDIV
.
When doing diviation,
AX
will be the dividend andBX
will be the divisor:idiv bx
==ax / bx
Carry of multiplication
- When doing 8-bit multiplication, we will use the whole
AX
to store the possibly 16-bit answer. - When doing 16-bit multiplication, we will use
DX
andAX
to store the possibly 32-bit answer, with the more significant word stored inDX
(For example for a 32-bit number:12345678h
=>DX: 1234h
AX: 5678h
).
Even if the result is not out of the range of 16-bit, the DX
will also be updated to 0000f
.
Since we have reserved enough place for this result, so there is no such Carry or Overflow in MUL
and IMUL
.
Division
Similar to multiplication, division operation also use AX
and DX
. Means if you want to doing 16-bit operation, you need to set DX
to 0000f
first.
For example:
mov ax, 6
mov bx, 3
div bx
You may supposed that you get a 0002h
in AX
, but actually the result is unpredictable as we don't know what's the value in DS
. If DX = 0001h
, then you will actually get `
Run the ASM code above to try it yourself.
Increase & Decrease
INC
and DEC
is quite like the ++
and --
operator in C/C++
. In old processors, INC AX
would be faster than doing ADD AX, 1
No comment