Rev 4805 | Rev 5419 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4805 | Rev 5391 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2010-2014. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; zeroconfig.asm - Zeroconfig service for KolibriOS ;; |
6 | ;; zeroconfig.asm - Zeroconfig service for KolibriOS ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
Line 60... | Line 60... | ||
60 | include '../../debug-fdo.inc' |
60 | include '../../debug-fdo.inc' |
61 | include '../../network.inc' |
61 | include '../../network.inc' |
62 | include 'dhcp.inc' |
62 | include 'dhcp.inc' |
63 | include '../../dll.inc' |
63 | include '../../dll.inc' |
Line -... | Line 64... | ||
- | 64 | ||
- | 65 | START: |
|
Line 64... | Line -... | ||
64 | - | ||
65 | - | ||
66 | Ip2dword: |
- | |
67 | push edx |
- | |
68 | - | ||
69 | ; This code validates if the query is an IP containing 4 numbers and 3 dots |
- | |
70 | - | ||
71 | xor al, al ; make al (dot count) zero |
- | |
72 | - | ||
73 | @@: |
66 | mcall 68, 11 |
74 | cmp byte[edx],'0' ; check if this byte is a number, if not jump to no_IP |
- | |
75 | jl no_IP ; |
67 | |
76 | cmp byte[edx],'9' ; |
- | |
77 | jg no_IP ; |
- | |
78 | - | ||
79 | inc edx ; the byte was a number, so lets check the next byte |
- | |
80 | - | ||
81 | cmp byte[edx],0 ; is this byte zero? (have we reached end of query?) |
- | |
82 | jz @f ; jump to next @@ then |
68 | stdcall dll.Load,@IMPORT |
83 | cmp byte[edx],':' |
- | |
84 | jz @f |
- | |
85 | - | ||
86 | cmp byte[edx],'.' ; is this byte a dot? |
- | |
87 | jne @r ; if not, jump to previous @@ |
- | |
88 | - | ||
89 | inc al ; the byte was a dot so increment al(dot count) |
- | |
90 | inc edx ; next byte |
- | |
91 | jmp @r ; lets check for numbers again (jump to previous @@) |
- | |
92 | - | ||
93 | @@: ; we reach this when end of query reached |
- | |
Line 94... | Line 69... | ||
94 | cmp al,3 ; check if there where 3 dots |
69 | or eax, eax |
95 | jnz no_IP ; if not, jump to no_IP |
- | |
Line 96... | Line 70... | ||
96 | 70 | jnz fail |
|
Line -... | Line 71... | ||
- | 71 | ||
97 | ; The following code will convert this IP into a dword and output it in eax |
72 | DEBUGF 2,"Zero-config service loaded\n" |
98 | ; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1 |
73 | |
- | 74 | mcall 40, EVM_STACK2 |
|
99 | 75 | ||
- | 76 | wait_for_link_up: |
|
Line 100... | Line -... | ||
100 | pop esi ; edx (query address) was pushed onto stack and is now popped in esi |
- | |
101 | - | ||
102 | xor edx, edx ; result |
77 | mov bh, [device] |
103 | xor eax, eax ; current character |
78 | mov bl, 0 ; Get device type |
104 | xor ebx, ebx ; current byte |
- | |
105 | - | ||
106 | .outer_loop: |
79 | mcall 74 |
107 | shl edx, 8 |
- | |
108 | add edx, ebx |
- | |
109 | xor ebx, ebx |
- | |
110 | .inner_loop: |
- | |
111 | lodsb |
- | |
112 | test eax, eax |
- | |
113 | jz .finish |
- | |
114 | cmp al, '.' |
- | |
115 | jz .outer_loop |
- | |
116 | sub eax, '0' |
- | |
117 | imul ebx, 10 |
- | |
118 | add ebx, eax |
- | |
119 | jmp .inner_loop |
- | |
120 | .finish: |
- | |
121 | shl edx, 8 |
- | |
122 | add edx, ebx |
- | |
123 | 80 | cmp eax, 1 ; Ethernet |
|
124 | bswap edx ; we want little endian order |
- | |
125 | - | ||
126 | ret |
- | |
127 | - | ||
128 | no_IP: |
- | |
129 | pop edx |
- | |
130 | xor edx, edx |
- | |
131 | - | ||
132 | ret |
- | |
133 | - | ||
134 | - | ||
135 | - | ||
136 | - | ||
Line 137... | Line 81... | ||
137 | 81 | jne .wait |
|
138 | - | ||
139 | START: |
- | |
140 | mcall 40, EVM_STACK2 |
- | |
141 | - | ||
142 | DEBUGF 2,"Zero-config service loaded\n" |
- | |
143 | - | ||
144 | .wait: |
82 | |
145 | mov ebx, API_ETH + 0 |
83 | mov bl, 10 ; Get Link status |
Line 146... | Line 84... | ||
146 | mov bh, [device] |
84 | mcall 74 |
- | 85 | test eax, eax |
|
- | 86 | jnz .go |
|
- | 87 | ||
147 | mcall 76 ; get MAC of ethernet interface 1 |
88 | .wait: |
148 | cmp eax, -1 |
89 | mcall 10 |
149 | jne .start |
90 | jmp wait_for_link_up |
Line 150... | Line 91... | ||
150 | 91 | ||
Line -... | Line 92... | ||
- | 92 | .go: |
|
151 | mcall 10 |
93 | mov ebx, API_ETH + 0 |
- | 94 | mov bh, [device] |
|
Line 152... | Line -... | ||
152 | jmp .wait |
- | |
153 | 95 | mcall 76 ; get MAC of the ethernet interface |
|
154 | .start: |
96 | mov word[MAC], bx |
Line -... | Line 97... | ||
- | 97 | mov dword[MAC+2], eax |
|
- | 98 | DEBUGF 1,"MAC: %x-%x-%x-%x-%x-%x\n", [MAC+0]:2, [MAC+1]:2, [MAC+2]:2, [MAC+3]:2, [MAC+4]:2, [MAC+5]:2 |
|
- | 99 | ||
- | 100 | invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0 |
|
155 | mov word[MAC], bx |
101 | |
- | 102 | cmp dword[inibuf], 'stat' |
|
- | 103 | je static |
|
- | 104 | jmp try_dhcp |
|
Line -... | Line 105... | ||
- | 105 | ||
- | 106 | wait_for_link_down: |
|
156 | mov dword[MAC+2], eax |
107 | ; TODO: detect ARP conflicts |
157 | DEBUGF 1,"MAC: %x-%x-%x-%x-%x-%x\n", [MAC+0]:2, [MAC+1]:2, [MAC+2]:2, [MAC+3]:2, [MAC+4]:2, [MAC+5]:2 |
108 | |
- | 109 | mcall 40, EVM_STACK2 |
|
- | 110 | .loop: |
|
- | 111 | mcall 10 |
|
- | 112 | mov bh, [device] |
|
- | 113 | mov bl, 0 ; Get device type |
|
- | 114 | mcall 74 |
|
- | 115 | cmp eax, 0 ; No device |
|
- | 116 | je .down |
|
- | 117 | ||
- | 118 | mov bl, 10 ; Get Link status |
|
- | 119 | mcall 74 |
|
- | 120 | test eax, eax |
|
- | 121 | jnz .loop |
|
- | 122 | ||
- | 123 | .down: |
|
- | 124 | xor ecx, ecx |
|
- | 125 | mov ebx, API_IPv4 + 3 |
|
Line 158... | Line 126... | ||
158 | 126 | mov bh, [device] |
|
159 | mcall 40, EVM_STACK |
127 | mcall 76 ; ip |
160 | 128 | mov bl, 5 |
|
161 | mcall 68, 11 |
129 | mcall 76 ; dns |
162 | 130 | mov bl, 7 |
|
163 | stdcall dll.Load,@IMPORT |
131 | mcall 76 ; subnet |
164 | or eax, eax |
132 | mov bl, 9 |
Line 165... | Line 133... | ||
165 | jnz try_dhcp |
133 | mcall 76 ; gateway |
166 | 134 | ||
167 | invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0 |
135 | jmp wait_for_link_up |
168 | 136 | ||
169 | cmp dword[inibuf], 'stat' |
137 | static: |
170 | jne try_dhcp |
138 | DEBUGF 1,"Applying Static IP settings\n" |
171 | 139 | ||
Line 172... | Line 140... | ||
172 | invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0 |
140 | invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0 |
173 | mov edx, inibuf |
141 | mov edx, inibuf |
174 | call Ip2dword |
142 | call ip_str_to_dword |
175 | mov ecx, edx |
143 | mov ecx, edx |
176 | mov ebx, API_IPv4 + 3 ; set IP |
144 | mov ebx, API_IPv4 + 3 ; set IP |
177 | mov bh, [device] |
145 | mov bh, [device] |
178 | mcall 76 |
146 | mcall 76 |
Line 179... | Line 147... | ||
179 | 147 | ||
180 | invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0 |
148 | invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0 |
181 | mov edx, inibuf |
149 | mov edx, inibuf |
182 | call Ip2dword |
150 | call ip_str_to_dword |
183 | mov ecx, edx |
151 | mov ecx, edx |
184 | mov ebx, API_IPv4 + 9 ; set gateway |
152 | mov ebx, API_IPv4 + 9 ; set gateway |
185 | mov bh, [device] |
153 | mov bh, [device] |
Line 186... | Line -... | ||
186 | mcall 76 |
- | |
- | 154 | mcall 76 |
|
187 | 155 | ||
- | 156 | invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0 |
|
Line 188... | Line 157... | ||
188 | invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0 |
157 | mov edx, inibuf |
Line 189... | Line 158... | ||
189 | mov edx, inibuf |
158 | call ip_str_to_dword |
Line -... | Line 159... | ||
- | 159 | mov ecx, edx |
|
- | 160 | mov ebx, API_IPv4 + 5 ; set DNS |
|
190 | call Ip2dword |
161 | mov bh, [device] |
191 | mov ecx, edx |
162 | mcall 76 |
192 | mov ebx, API_IPv4 + 5 ; set DNS |
163 | |
193 | mov bh, [device] |
164 | invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0 |
Line 194... | Line 165... | ||
194 | mcall 76 |
165 | mov edx, inibuf |
Line 195... | Line 166... | ||
195 | 166 | call ip_str_to_dword |
|
196 | invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0 |
167 | mov ecx, edx |
197 | mov edx, inibuf |
168 | mov ebx, API_IPv4 + 7 ; set subnet |
Line 198... | Line 169... | ||
198 | call Ip2dword |
169 | mov bh, [device] |
Line 199... | Line 170... | ||
199 | mov ecx, edx |
170 | mcall 76 |
200 | mov ebx, API_IPv4 + 7 ; set subnet |
171 | |
201 | mov bh, [device] |
172 | mov [notify_struct.msg], str_connected |
Line 202... | Line 173... | ||
202 | mcall 76 |
173 | mcall 70, notify_struct |
Line 203... | Line 174... | ||
203 | 174 | jmp wait_for_link_down |
|
204 | 175 | ||
Line 240... | Line 211... | ||
240 | mov [tries], DHCP_TRIES |
211 | mov [tries], DHCP_TRIES |
Line 241... | Line 212... | ||
241 | 212 | ||
Line 242... | Line 213... | ||
242 | DEBUGF 1,"Building request\n" |
213 | DEBUGF 1,"Building request\n" |
243 | - | ||
244 | stdcall mem.Alloc, BUFFER |
214 | |
245 | mov [dhcpMsg], eax |
215 | stdcall mem.Alloc, BUFFER |
246 | test eax, eax |
- | |
247 | jz dhcp_error |
216 | test eax, eax |
Line 248... | Line 217... | ||
248 | 217 | jz dhcp_fail2 |
|
249 | ;;; todo: skip this bullcrap |
218 | mov [dhcpMsg], eax |
250 | 219 | ||
251 | mov edi, eax |
220 | mov edi, eax |
Line 252... | Line 221... | ||
252 | mov ecx, BUFFER |
221 | mov ecx, BUFFER |
Line 253... | Line 222... | ||
253 | xor eax, eax |
222 | xor eax, eax |
Line 254... | Line 223... | ||
254 | rep stosb |
223 | rep stosb |
255 | 224 | ||
256 | ;; todo: put this in a buffer instead of writing bytes and words! |
225 | ;; todo: put this in one buffer we can copy, instead of writing bytes and words! |
257 | 226 | ||
258 | mov edx, [dhcpMsg] |
227 | mov edx, [dhcpMsg] |
259 | 228 | ||
260 | ; Boot protocol legacy |
229 | ; Boot protocol legacy |
261 | mov [edx], byte 0x01 ; Boot request |
230 | mov [edx], byte 0x01 ; Boot request |
262 | mov [edx+1], byte 0x01 ; Ethernet |
231 | mov [edx+1], byte 0x01 ; Ethernet |
263 | mov [edx+2], byte 0x06 ; Ethernet h/w len |
232 | mov [edx+2], byte 0x06 ; Ethernet h/w len |
Line 306... | Line 275... | ||
306 | mcall 75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen] ; write to socket ( send broadcast request ) |
275 | mcall 75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen] ; write to socket (send broadcast request) |
307 | mcall 26, 9 |
276 | mcall 26, 9 |
308 | add eax, TIMEOUT*100 |
277 | add eax, TIMEOUT*100 |
309 | mov [timeout], eax |
278 | mov [timeout], eax |
310 | .wait: |
279 | .wait: |
311 | mcall 23, TIMEOUT ; wait for data |
280 | mcall 23, TIMEOUT ; wait for data (with timeout) |
Line 312... | Line 281... | ||
312 | 281 | ||
313 | read_data: ; we have data - this will be the response |
282 | read_data: ; we have data - this will be the response |
314 | mcall 75, 7, [socketNum], [dhcpMsg], BUFFER, MSG_DONTWAIT ; read data from socket |
283 | mcall 75, 7, [socketNum], [dhcpMsg], BUFFER, MSG_DONTWAIT ; read data from socket |
315 | cmp eax, -1 |
284 | cmp eax, -1 |
Line 320... | Line 289... | ||
320 | jb send_dhcpmsg.wait |
289 | jb send_dhcpmsg.wait |
Line 321... | Line 290... | ||
321 | 290 | ||
322 | DEBUGF 2,"No answer from DHCP server\n" |
291 | DEBUGF 2,"No answer from DHCP server\n" |
323 | dec [tries] |
292 | dec [tries] |
324 | jnz send_dhcpmsg ; try again |
293 | jnz send_dhcpmsg ; try again |
Line 325... | Line 294... | ||
325 | jmp dhcp_error ; fail |
294 | jmp dhcp_fail |
326 | 295 | ||
327 | @@: |
296 | @@: |
Line 342... | Line 311... | ||
342 | je discover |
311 | je discover |
Line 343... | Line 312... | ||
343 | 312 | ||
344 | cmp [dhcpMsgType], 0x03 ; did we send a request? |
313 | cmp [dhcpMsgType], 0x03 ; did we send a request? |
Line 345... | Line 314... | ||
345 | je request |
314 | je request |
346 | 315 | ||
Line 347... | Line 316... | ||
347 | call dhcp_end ; we should never reach here ;) |
316 | ; we should never reach here ;) |
348 | jmp exit |
317 | jmp fail |
Line 349... | Line 318... | ||
349 | 318 | ||
350 | discover: |
- | |
351 | call parse_response |
- | |
352 | 319 | discover: |
|
353 | cmp [dhcpMsgType2], 0x02 ; Was the response an offer? |
- | |
Line 354... | Line -... | ||
354 | je send_request |
- | |
355 | 320 | call parse_response |
|
356 | call dhcp_end |
321 | |
357 | jmp link_local |
322 | cmp [dhcpMsgType2], 0x02 ; Was the response an offer? |
Line 358... | Line 323... | ||
358 | 323 | jne dhcp_fail |
|
359 | send_request: |
324 | |
Line 360... | Line 325... | ||
360 | DEBUGF 1, "Got offer, making request\n" |
325 | DEBUGF 1, "Got offer, making request\n" |
361 | mov [dhcpMsgType], 0x03 ; make it a request |
326 | mov [dhcpMsgType], 0x03 ; make it a request |
Line 362... | Line 327... | ||
362 | jmp build_request |
327 | jmp build_request |
Line 363... | Line 328... | ||
363 | 328 | ||
364 | request: |
329 | request: |
365 | call parse_response |
330 | call parse_response |
Line 366... | Line 331... | ||
366 | 331 | ||
367 | cmp [dhcpMsgType2], 0x05 ; Was the response an ACK? It should be |
332 | cmp [dhcpMsgType2], 0x05 ; Was the response an ACK? It should be |
368 | jne read_data ; NO - read next packets |
333 | jne read_data ; NO - read next packets |
369 | 334 | ||
Line 381... | Line 346... | ||
381 | mov bl, 7 |
346 | mov bl, 7 |
382 | mcall 76, , [dhcp.subnet] ; subnet |
347 | mcall 76, , [dhcp.subnet] ; subnet |
383 | mov bl, 9 |
348 | mov bl, 9 |
384 | mcall 76, , [dhcp.gateway] ; gateway |
349 | mcall 76, , [dhcp.gateway] ; gateway |
Line 385... | Line 350... | ||
385 | 350 | ||
386 | jmp exit |
- | |
387 | - | ||
388 | dhcp_end: |
- | |
389 | mcall close, [socketNum] |
- | |
Line 390... | Line -... | ||
390 | stdcall mem.Free, [dhcpMsg] |
- | |
Line 391... | Line 351... | ||
391 | 351 | jmp wait_for_link_down |
|
392 | ret |
352 | |
393 | 353 | ||
394 | ;*************************************************************************** |
354 | ;*************************************************************************** |
Line 479... | Line 439... | ||
479 | .lease: |
439 | .lease: |
480 | pusha |
440 | pusha |
481 | mov eax,[edx] |
441 | mov eax,[edx] |
482 | bswap eax |
442 | bswap eax |
483 | mov [dhcpLease],eax |
443 | mov [dhcpLease],eax |
484 | DEBUGF 1,"lease: %d\n",eax |
444 | DEBUGF 1,"Lease: %d\n",eax |
485 | popa |
445 | popa |
486 | jmp .next_option |
446 | jmp .next_option |
Line 487... | Line 447... | ||
487 | 447 | ||
488 | .subnet: |
448 | .subnet: |
Line 504... | Line 464... | ||
504 | jmp .next_option |
464 | jmp .next_option |
Line 505... | Line 465... | ||
505 | 465 | ||
506 | .done: |
466 | .done: |
Line -... | Line 467... | ||
- | 467 | ret |
|
Line -... | Line 468... | ||
- | 468 | ||
- | 469 | dhcp_fail: |
|
Line 507... | Line 470... | ||
507 | ret |
470 | |
508 | 471 | mcall close, [socketNum] |
|
Line 509... | Line 472... | ||
509 | 472 | stdcall mem.Free, [dhcpMsg] |
|
510 | 473 | ||
511 | dhcp_error: |
474 | dhcp_fail2: |
512 | call dhcp_end |
475 | DEBUGF 1,"DHCP failed\n" |
Line 575... | Line 538... | ||
575 | 538 | ||
576 | DEBUGF 1,"Waiting %us\n", ANNOUNCE_INTERVAL |
539 | DEBUGF 1,"Waiting %us\n", ANNOUNCE_INTERVAL |
577 | mcall 5, ANNOUNCE_INTERVAL*100 |
540 | mcall 5, ANNOUNCE_INTERVAL*100 |
578 | jmp announce_loop |
541 | jmp announce_loop |
579 | @@: |
542 | @@: |
Line 580... | Line 543... | ||
580 | jmp exit |
543 | jmp wait_for_link_down |
581 | 544 | ||
582 | - | ||
- | 545 | ||
583 | error: |
546 | socket_error: |
584 | DEBUGF 2,"Socket error\n" |
547 | DEBUGF 2,"Socket error\n" |
Line 585... | Line 548... | ||
585 | exit: ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;) |
548 | fail: |
Line 598... | Line 561... | ||
598 | xor eax, dword[MAC+2] |
561 | xor eax, dword[MAC+2] |
599 | mov [generator], eax |
562 | mov [generator], eax |
Line 600... | Line 563... | ||
600 | 563 | ||
Line -... | Line 564... | ||
- | 564 | ret |
|
- | 565 | ||
- | 566 | ||
- | 567 | ||
- | 568 | ip_str_to_dword: |
|
- | 569 | push edx |
|
- | 570 | ||
- | 571 | ; This code validates if the query is an IP containing 4 numbers and 3 dots |
|
- | 572 | ||
- | 573 | xor al, al ; make al (dot count) zero |
|
- | 574 | ||
- | 575 | @@: |
|
- | 576 | cmp byte[edx],'0' ; check if this byte is a number, if not jump to no_IP |
|
- | 577 | jl no_IP ; |
|
- | 578 | cmp byte[edx],'9' ; |
|
- | 579 | jg no_IP ; |
|
- | 580 | ||
- | 581 | inc edx ; the byte was a number, so lets check the next byte |
|
- | 582 | ||
- | 583 | cmp byte[edx],0 ; is this byte zero? (have we reached end of query?) |
|
- | 584 | jz @f ; jump to next @@ then |
|
- | 585 | cmp byte[edx],':' |
|
- | 586 | jz @f |
|
- | 587 | ||
- | 588 | cmp byte[edx],'.' ; is this byte a dot? |
|
- | 589 | jne @r ; if not, jump to previous @@ |
|
- | 590 | ||
- | 591 | inc al ; the byte was a dot so increment al(dot count) |
|
- | 592 | inc edx ; next byte |
|
- | 593 | jmp @r ; lets check for numbers again (jump to previous @@) |
|
- | 594 | ||
- | 595 | @@: ; we reach this when end of query reached |
|
- | 596 | cmp al,3 ; check if there where 3 dots |
|
- | 597 | jnz no_IP ; if not, jump to no_IP |
|
- | 598 | ||
- | 599 | ; The following code will convert this IP into a dword and output it in eax |
|
- | 600 | ; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1 |
|
- | 601 | ||
- | 602 | pop esi ; edx (query address) was pushed onto stack and is now popped in esi |
|
- | 603 | ||
- | 604 | xor edx, edx ; result |
|
- | 605 | xor eax, eax ; current character |
|
- | 606 | xor ebx, ebx ; current byte |
|
- | 607 | ||
- | 608 | .outer_loop: |
|
- | 609 | shl edx, 8 |
|
- | 610 | add edx, ebx |
|
- | 611 | xor ebx, ebx |
|
- | 612 | .inner_loop: |
|
- | 613 | lodsb |
|
- | 614 | test eax, eax |
|
- | 615 | jz .finish |
|
- | 616 | cmp al, '.' |
|
- | 617 | jz .outer_loop |
|
- | 618 | sub eax, '0' |
|
- | 619 | imul ebx, 10 |
|
- | 620 | add ebx, eax |
|
- | 621 | jmp .inner_loop |
|
- | 622 | .finish: |
|
- | 623 | shl edx, 8 |
|
- | 624 | add edx, ebx |
|
- | 625 | ||
- | 626 | bswap edx ; we want little endian order |
|
- | 627 | ||
- | 628 | ret |
|
- | 629 | ||
- | 630 | no_IP: |
|
- | 631 | pop edx |
|
- | 632 | xor edx, edx |
|
- | 633 | ||
601 | ret |
634 | ret |
Line 602... | Line 635... | ||
602 | 635 | ||
603 | ; DATA AREA |
636 | ; DATA AREA |