-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfpu_sqrt_lst.asm
222 lines (222 loc) · 16.7 KB
/
fpu_sqrt_lst.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
1 ;-----------------------------------------------------------------------------
2
3 ;-----------------------------------------------------------------------------
4
5 org 0x100 ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
6
7 start:
8 00000000 EB5C jmp main ; skok na zacatek kodu
9
10 %include "io.asm" ; nacist symboly, makra a podprogramy
1 <1> ;-----------------------------------------------------------------------------
2 <1> ; Symboly, makra a subrutiny pro zjednoduseni I/O operaci
3 <1> ;-----------------------------------------------------------------------------
4 <1>
5 <1> %ifndef IO_LIB
6 <1> %define IO_LIB
7 <1>
8 <1>
9 <1> ;-----------------------------------------------------------------------------
10 <1> ; makra
11 <1> ;-----------------------------------------------------------------------------
12 <1>
13 <1>
14 <1> ; ukonceni procesu a navrat do DOSu
15 <1> %macro exit 0
16 <1> mov ah, 0x4c
17 <1> int 0x21
18 <1> %endmacro
19 <1>
20 <1> ; vyprazdneni bufferu klavesnice a cekani na klavesu
21 <1> %macro wait_key 0
22 <1> xor ax, ax
23 <1> int 0x16
24 <1> %endmacro
25 <1>
26 <1> %endif
11 %include "print.asm" ; nacist symboly, makra a podprogramy
1 <1> ;-----------------------------------------------------------------------------
2 <1> ; Symboly, makra a subrutiny pro tisk hodnot na standardni vystup
3 <1> ;-----------------------------------------------------------------------------
4 <1>
5 <1> %ifndef PRINT_LIB
6 <1> %define PRINT_LIB
7 <1>
8 <1>
9 <1> ;-----------------------------------------------------------------------------
10 <1> ; makra
11 <1> ;-----------------------------------------------------------------------------
12 <1>
13 <1> ; makro pro tisk retezce na obrazovku
14 <1> %macro print_string 1
15 <1> mov dx, %1
16 <1> mov ah, 9
17 <1> int 0x21
18 <1> %endmacro
19 <1>
20 <1> ; makro pro tisk 32bitove hexadecimalni hodnoty
21 <1> ; na standardni vystup
22 <1> %macro print_hex 1
23 <1> pusha ; uchovat vsechny registry
24 <1> mov edx, %1 ; zapamatovat si hodnotu pro tisk
25 <1> mov ebx, hex_message ; buffer, ktery se zaplni hexa cislicemi
26 <1> call hex2string ; zavolani prislusne subrutiny
27 <1> print_string hex_message ; tisk hexadecimalni hodnoty
28 <1> popa ; obnovit vsechny registry
29 <1> %endmacro
30 <1>
31 <1> ; makro pro vypis 32bitove desitkove hodnoty na standardni vystup
32 <1> %macro print_dec 1
33 <1> pusha ; uschovat vsechny registry na zasobnik
34 <1> mov eax, %1 ; hodnotu pro tisk ulozit do registru EAX
35 <1> mov ebx, dec_message ; buffer, ktery se zaplni desitkovymi cisticemi
36 <1> call decimal2string ; zavolani prislusne subrutiny pro prevod na string
37 <1> print_string dec_message ; tisk hexadecimalni hodnoty
38 <1> popa ; obnovit vsechny registry
39 <1> %endmacro
40 <1>
41 <1> ; makro pro vypis obsahu FP hodnoty z vrcholu zasobniku ve forme hexadecimalniho cisla
42 <1> %macro print_float32_as_hex 0
43 <1> fstp dword [float32] ; ulozeni do pameti (4 bajty)
44 <1> mov eax, [float32] ; nacteni FP hodnoty do celociselneho registru
45 <1> print_hex eax ; zobrazeni obsahu tohoto registru v hexadecimalnim tvaru
46 <1> %endmacro
47 <1>
48 <1> ; makro pro vypis obsahu FP hodnoty z vrcholu zasobniku ve forme hexadecimalniho cisla
49 <1> %macro print_float64_as_hex 0
50 <1> fstp qword [float64] ; ulozeni do pameti (8 bajtu)
51 <1> mov eax, [float64+4]; nacteni FP hodnoty do celociselneho registru
52 <1> print_hex eax ; zobrazeni obsahu tohoto registru v hexadecimalnim tvaru
53 <1> mov eax, [float64] ; nacteni FP hodnoty do celociselneho registru
54 <1> print_hex eax ; zobrazeni obsahu tohoto registru v hexadecimalnim tvaru
55 <1> %endmacro
56 <1>
57 <1>
58 <1> ;-----------------------------------------------------------------------------
59 <1> ; subrutiny
60 <1> ;-----------------------------------------------------------------------------
61 <1>
62 <1> ; subrutina urcena pro prevod 32bitove hexadecimalni hodnoty na retezec
63 <1> ; Vstup: EDX - hodnota, ktera se ma prevest na retezec
64 <1> ; EBX - adresa jiz drive alokovaneho retezce (resp. osmice bajtu)
65 <1> hex2string:
66 00000002 B108 <1> mov cl, 8 ; pocet opakovani smycky
67 <1>
68 00000004 66C1C204 <1> .print_one_digit: rol edx, 4 ; rotace doleva znamena, ze se do spodnich 4 bitu nasune dalsi cifra
69 00000008 88D0 <1> mov al, dl ; nechceme porusit obsah vstupni hodnoty v EDX, proto pouzijeme AL
70 0000000A 240F <1> and al, 0x0f ; maskovani, potrebujeme pracovat jen s jednou cifrou
71 0000000C 3C0A <1> cmp al, 10 ; je cifra vetsi nebo rovna 10?
72 0000000E 7C02 <1> jl .store_digit ; neni, pouze prevest 0..9 na ASCII hodnotu '0'..'9'
73 <1>
74 00000010 0407 <1> .alpha_digit: add al, 'A'-10-'0' ; prevod hodnoty 10..15 na znaky 'A'..'F'
75 <1>
76 00000012 0430 <1> .store_digit: add al, '0'
77 00000014 678803 <1> mov [ebx], al ; ulozeni cifry do retezce
78 00000017 6643 <1> inc ebx ; dalsi ulozeni v retezci o znak dale
79 00000019 FEC9 <1> dec cl ; snizeni pocitadla smycky
80 0000001B 75E7 <1> jnz .print_one_digit ; a opakovani smycky, dokud se nedosahlo nuly
81 <1>
82 0000001D C3 <1> ret ; navrat ze subrutiny
83 <1>
84 <1>
85 <1> ; subrutina urcena pro prevod 32bitove desitkove hodnoty na retezec
86 <1> ; Vstup: EDX - hodnota, ktera se ma prevest na retezec
87 <1> ; EBX - adresa jiz drive alokovaneho retezce (resp. minimalne deseti bajtu)
88 <1> decimal2string:
89 0000001E 66B90A000000 <1> mov ecx, 10 ; celkovy pocet zapisovanych cifer/znaku
90 00000024 6689CF <1> mov edi, ecx ; instrukce DIV vyzaduje deleni registrem, pouzijme tedy EDI
91 <1>
92 <1> .next_digit:
93 00000027 6631D2 <1> xor edx, edx ; delenec je dvojice EDX:EAX, vynulujeme tedy horni registr EDX
94 0000002A 66F7F7 <1> div edi ; deleni hodnoty ulozene v EDX:EAX deseti (delitelem je EDI)
95 <1> ; vysledek se ulozi do EAX, zbytek do EDX
96 <1> ; pri deleni deseti je jistota, ze zbytek je jen cislo 0..9
97 <1>
98 0000002D 80C230 <1> add dl, '0' ; prevod hodnoty 0..9 na znak '0'-'9'
99 <1>
100 00000030 6788540BFF <1> mov [ebx+ecx-1], dl ; zapis retezce (od posledniho znaku)
101 <1>
102 00000035 6649 <1> dec ecx ; presun na predchozi znak v retezci a soucasne snizeni hodnoty pocitadla
103 00000037 75EE <1> jnz .next_digit ; uz jsme dosli k poslednimu cislu?
104 <1>
105 00000039 C3 <1> ret ; navrat ze subrutiny
106 <1>
107 <1>
108 <1> ;-----------------------------------------------------------------------------
109 <1> ; buffery
110 <1> ;-----------------------------------------------------------------------------
111 <1>
112 <1> ; retezec ukonceny znakem $
113 <1> ; (tato data jsou soucasti vysledneho souboru typu COM)
114 <1> hex_message:
115 0000003A 3F<rep 8h> <1> times 8 db '?',
116 00000042 0D0A24 <1> db 0x0d, 0x0a, "$"
117 <1>
118 <1> ; retezec ukonceny znakem $
119 <1> ; (tato data jsou soucasti vysledneho souboru typu COM)
120 <1> dec_message:
121 00000045 3F<rep Ah> <1> times 10 db '?',
122 0000004F 0D0A24 <1> db 0x0d, 0x0a, "$"
123 <1>
124 00000052 00000000 <1> float32: dd 0
125 00000056 0000000000000000 <1> float64: dq 0
126 <1>
127 <1> %endif
12
13 main:
14 0000005E D9EE fldz ; nacteni FP konstanty 0.0
15 00000060 D9FA fsqrt ; vypocet druhe odmocniny
16 print_float32_as_hex ; zobrazeni FP hodnoty v hexadecimalnim tvaru
43 00000062 D91E[5200] <1> fstp dword [float32]
44 00000066 66A1[5200] <1> mov eax, [float32]
45 <1> print_hex eax
23 0000006A 60 <2> pusha
24 0000006B 6689C2 <2> mov edx, %1
25 0000006E 66BB[3A000000] <2> mov ebx, hex_message
26 00000074 E88BFF <2> call hex2string
27 <2> print_string hex_message
15 00000077 BA[3A00] <3> mov dx, %1
16 0000007A B409 <3> mov ah, 9
17 0000007C CD21 <3> int 0x21
28 0000007E 61 <2> popa
17
18 0000007F D9E8 fld1 ; nacteni FP konstanty 1.0
19 00000081 D9FA fsqrt ; vypocet druhe odmocniny
20 print_float32_as_hex ; zobrazeni FP hodnoty v hexadecimalnim tvaru
43 00000083 D91E[5200] <1> fstp dword [float32]
44 00000087 66A1[5200] <1> mov eax, [float32]
45 <1> print_hex eax
23 0000008B 60 <2> pusha
24 0000008C 6689C2 <2> mov edx, %1
25 0000008F 66BB[3A000000] <2> mov ebx, hex_message
26 00000095 E86AFF <2> call hex2string
27 <2> print_string hex_message
15 00000098 BA[3A00] <3> mov dx, %1
16 0000009B B409 <3> mov ah, 9
17 0000009D CD21 <3> int 0x21
28 0000009F 61 <2> popa
21
22 000000A0 D9E8 fld1 ; nacteni FP konstanty 1.0
23 000000A2 D9E8 fld1 ; nacteni FP konstanty 1.0
24 000000A4 DEC1 faddp ; soucet -> na zasobnik se ulozi hodnota 2.0
25 000000A6 D9FA fsqrt ; vypocet druhe odmocniny
26 print_float32_as_hex ; zobrazeni FP hodnoty v hexadecimalnim tvaru
43 000000A8 D91E[5200] <1> fstp dword [float32]
44 000000AC 66A1[5200] <1> mov eax, [float32]
45 <1> print_hex eax
23 000000B0 60 <2> pusha
24 000000B1 6689C2 <2> mov edx, %1
25 000000B4 66BB[3A000000] <2> mov ebx, hex_message
26 000000BA E845FF <2> call hex2string
27 <2> print_string hex_message
15 000000BD BA[3A00] <3> mov dx, %1
16 000000C0 B409 <3> mov ah, 9
17 000000C2 CD21 <3> int 0x21
28 000000C4 61 <2> popa
27
28 wait_key ; cekani na klavesu
22 000000C5 31C0 <1> xor ax, ax
23 000000C7 CD16 <1> int 0x16
29 exit ; navrat do DOSu
16 000000C9 B44C <1> mov ah, 0x4c
17 000000CB CD21 <1> int 0x21