forked from cirosantilli/x86-assembly-cheat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
div.asm
83 lines (62 loc) · 1.82 KB
/
div.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
; # DIV
; Signed division:
; eax = edx:eax / SRC
; edx = edx:eax % SRC
; # Modulo
; div can be used to calculate modulus, but GCC does not use it becaues it is slow,
; and choses alternative techniques instead instead:
; http://stackoverflow.com/questions/4361979/how-does-the-gcc-implementation-of-module-work-and-why-does-it-not-use-the
%include "lib/asm_io.inc"
ENTRY
mov eax, 5
mov edx, 0
mov ecx, 2
div ecx
ASSERT_EQ 2
ASSERT_EQ edx, 1
; 8 bit
mov eax, 0
mov ax, 0x101
mov cl, 2
div cl
ASSERT_EQ 0x180
; 16 bit
mov eax, 0
mov edx, 0
mov ax, 1
mov dx, 1
mov cx, 2
div cx
ASSERT_EQ 0x8000
ASSERT_EQ edx, 1
; 32 bit
mov eax, 1
mov edx, 1
mov ecx, 2
div ecx
ASSERT_EQ 0x80000000
ASSERT_EQ edx, 1
; # Division by zero
; # Division overflow
; If either
; - divisor == 0
; - result > output register size
; A divide error exception occurs.
; It then gets handled by the interrupt service 0.
; Both 0 division and overflow are treated exactly the same!
; Linux treats this by sending a signal to the process and killing it.
; Minimal 16-bit example of handling the interrupt:
; https://github.com/cirosantilli/x86-bare-metal-examples/blob/9e58c1dc656dab54aa69daa38f84eb8c0aa6151e/idt_zero_divide.S
; Output does not fit into edx.
;mov eax, 0
;mov edx, 1
;mov ecx, 1
;div ecx
; Division by zero.
;mov eax, 1
;mov edx, 0
;mov ecx, 0
;div ecx
; There is no immediate version:
; http://stackoverflow.com/questions/4529260/mul-instruction-doesnt-support-an-immediate-value
EXIT