forked from KolibriOS/kolibrios
Connect to DHCP server only when link is active. (and reconnect when cable was reconnected)
git-svn-id: svn://kolibrios.org@5391 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
f2f52bfc14
commit
2fb146ac3e
@ -1,6 +1,6 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Copyright (C) KolibriOS team 2010-2014. All rights reserved. ;;
|
;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;;
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; zeroconfig.asm - Zeroconfig service for KolibriOS ;;
|
;; zeroconfig.asm - Zeroconfig service for KolibriOS ;;
|
||||||
@ -62,116 +62,84 @@ include '../../network.inc'
|
|||||||
include 'dhcp.inc'
|
include 'dhcp.inc'
|
||||||
include '../../dll.inc'
|
include '../../dll.inc'
|
||||||
|
|
||||||
|
|
||||||
Ip2dword:
|
|
||||||
push edx
|
|
||||||
|
|
||||||
; This code validates if the query is an IP containing 4 numbers and 3 dots
|
|
||||||
|
|
||||||
xor al, al ; make al (dot count) zero
|
|
||||||
|
|
||||||
@@:
|
|
||||||
cmp byte[edx],'0' ; check if this byte is a number, if not jump to no_IP
|
|
||||||
jl no_IP ;
|
|
||||||
cmp byte[edx],'9' ;
|
|
||||||
jg no_IP ;
|
|
||||||
|
|
||||||
inc edx ; the byte was a number, so lets check the next byte
|
|
||||||
|
|
||||||
cmp byte[edx],0 ; is this byte zero? (have we reached end of query?)
|
|
||||||
jz @f ; jump to next @@ then
|
|
||||||
cmp byte[edx],':'
|
|
||||||
jz @f
|
|
||||||
|
|
||||||
cmp byte[edx],'.' ; is this byte a dot?
|
|
||||||
jne @r ; if not, jump to previous @@
|
|
||||||
|
|
||||||
inc al ; the byte was a dot so increment al(dot count)
|
|
||||||
inc edx ; next byte
|
|
||||||
jmp @r ; lets check for numbers again (jump to previous @@)
|
|
||||||
|
|
||||||
@@: ; we reach this when end of query reached
|
|
||||||
cmp al,3 ; check if there where 3 dots
|
|
||||||
jnz no_IP ; if not, jump to no_IP
|
|
||||||
|
|
||||||
; The following code will convert this IP into a dword and output it in eax
|
|
||||||
; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1
|
|
||||||
|
|
||||||
pop esi ; edx (query address) was pushed onto stack and is now popped in esi
|
|
||||||
|
|
||||||
xor edx, edx ; result
|
|
||||||
xor eax, eax ; current character
|
|
||||||
xor ebx, ebx ; current byte
|
|
||||||
|
|
||||||
.outer_loop:
|
|
||||||
shl edx, 8
|
|
||||||
add edx, ebx
|
|
||||||
xor ebx, ebx
|
|
||||||
.inner_loop:
|
|
||||||
lodsb
|
|
||||||
test eax, eax
|
|
||||||
jz .finish
|
|
||||||
cmp al, '.'
|
|
||||||
jz .outer_loop
|
|
||||||
sub eax, '0'
|
|
||||||
imul ebx, 10
|
|
||||||
add ebx, eax
|
|
||||||
jmp .inner_loop
|
|
||||||
.finish:
|
|
||||||
shl edx, 8
|
|
||||||
add edx, ebx
|
|
||||||
|
|
||||||
bswap edx ; we want little endian order
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
no_IP:
|
|
||||||
pop edx
|
|
||||||
xor edx, edx
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
START:
|
START:
|
||||||
mcall 40, EVM_STACK2
|
|
||||||
|
|
||||||
DEBUGF 2,"Zero-config service loaded\n"
|
|
||||||
|
|
||||||
.wait:
|
|
||||||
mov ebx, API_ETH + 0
|
|
||||||
mov bh, [device]
|
|
||||||
mcall 76 ; get MAC of ethernet interface 1
|
|
||||||
cmp eax, -1
|
|
||||||
jne .start
|
|
||||||
|
|
||||||
mcall 10
|
|
||||||
jmp .wait
|
|
||||||
|
|
||||||
.start:
|
|
||||||
mov word[MAC], bx
|
|
||||||
mov dword[MAC+2], eax
|
|
||||||
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
|
|
||||||
|
|
||||||
mcall 40, EVM_STACK
|
|
||||||
|
|
||||||
mcall 68, 11
|
mcall 68, 11
|
||||||
|
|
||||||
stdcall dll.Load,@IMPORT
|
stdcall dll.Load,@IMPORT
|
||||||
or eax, eax
|
or eax, eax
|
||||||
jnz try_dhcp
|
jnz fail
|
||||||
|
|
||||||
|
DEBUGF 2,"Zero-config service loaded\n"
|
||||||
|
|
||||||
|
mcall 40, EVM_STACK2
|
||||||
|
|
||||||
|
wait_for_link_up:
|
||||||
|
mov bh, [device]
|
||||||
|
mov bl, 0 ; Get device type
|
||||||
|
mcall 74
|
||||||
|
cmp eax, 1 ; Ethernet
|
||||||
|
jne .wait
|
||||||
|
|
||||||
|
mov bl, 10 ; Get Link status
|
||||||
|
mcall 74
|
||||||
|
test eax, eax
|
||||||
|
jnz .go
|
||||||
|
|
||||||
|
.wait:
|
||||||
|
mcall 10
|
||||||
|
jmp wait_for_link_up
|
||||||
|
|
||||||
|
.go:
|
||||||
|
mov ebx, API_ETH + 0
|
||||||
|
mov bh, [device]
|
||||||
|
mcall 76 ; get MAC of the ethernet interface
|
||||||
|
mov word[MAC], bx
|
||||||
|
mov dword[MAC+2], eax
|
||||||
|
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
|
||||||
|
|
||||||
invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
|
invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
|
||||||
|
|
||||||
cmp dword[inibuf], 'stat'
|
cmp dword[inibuf], 'stat'
|
||||||
jne try_dhcp
|
je static
|
||||||
|
jmp try_dhcp
|
||||||
|
|
||||||
|
wait_for_link_down:
|
||||||
|
; TODO: detect ARP conflicts
|
||||||
|
|
||||||
|
mcall 40, EVM_STACK2
|
||||||
|
.loop:
|
||||||
|
mcall 10
|
||||||
|
mov bh, [device]
|
||||||
|
mov bl, 0 ; Get device type
|
||||||
|
mcall 74
|
||||||
|
cmp eax, 0 ; No device
|
||||||
|
je .down
|
||||||
|
|
||||||
|
mov bl, 10 ; Get Link status
|
||||||
|
mcall 74
|
||||||
|
test eax, eax
|
||||||
|
jnz .loop
|
||||||
|
|
||||||
|
.down:
|
||||||
|
xor ecx, ecx
|
||||||
|
mov ebx, API_IPv4 + 3
|
||||||
|
mov bh, [device]
|
||||||
|
mcall 76 ; ip
|
||||||
|
mov bl, 5
|
||||||
|
mcall 76 ; dns
|
||||||
|
mov bl, 7
|
||||||
|
mcall 76 ; subnet
|
||||||
|
mov bl, 9
|
||||||
|
mcall 76 ; gateway
|
||||||
|
|
||||||
|
jmp wait_for_link_up
|
||||||
|
|
||||||
|
static:
|
||||||
|
DEBUGF 1,"Applying Static IP settings\n"
|
||||||
|
|
||||||
invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
|
invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
|
||||||
mov edx, inibuf
|
mov edx, inibuf
|
||||||
call Ip2dword
|
call ip_str_to_dword
|
||||||
mov ecx, edx
|
mov ecx, edx
|
||||||
mov ebx, API_IPv4 + 3 ; set IP
|
mov ebx, API_IPv4 + 3 ; set IP
|
||||||
mov bh, [device]
|
mov bh, [device]
|
||||||
@ -179,7 +147,7 @@ START:
|
|||||||
|
|
||||||
invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
|
invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
|
||||||
mov edx, inibuf
|
mov edx, inibuf
|
||||||
call Ip2dword
|
call ip_str_to_dword
|
||||||
mov ecx, edx
|
mov ecx, edx
|
||||||
mov ebx, API_IPv4 + 9 ; set gateway
|
mov ebx, API_IPv4 + 9 ; set gateway
|
||||||
mov bh, [device]
|
mov bh, [device]
|
||||||
@ -187,7 +155,7 @@ START:
|
|||||||
|
|
||||||
invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
|
invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
|
||||||
mov edx, inibuf
|
mov edx, inibuf
|
||||||
call Ip2dword
|
call ip_str_to_dword
|
||||||
mov ecx, edx
|
mov ecx, edx
|
||||||
mov ebx, API_IPv4 + 5 ; set DNS
|
mov ebx, API_IPv4 + 5 ; set DNS
|
||||||
mov bh, [device]
|
mov bh, [device]
|
||||||
@ -195,36 +163,39 @@ START:
|
|||||||
|
|
||||||
invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
|
invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
|
||||||
mov edx, inibuf
|
mov edx, inibuf
|
||||||
call Ip2dword
|
call ip_str_to_dword
|
||||||
mov ecx, edx
|
mov ecx, edx
|
||||||
mov ebx, API_IPv4 + 7 ; set subnet
|
mov ebx, API_IPv4 + 7 ; set subnet
|
||||||
mov bh, [device]
|
mov bh, [device]
|
||||||
mcall 76
|
mcall 76
|
||||||
|
|
||||||
|
mov [notify_struct.msg], str_connected
|
||||||
mcall -1
|
mcall 70, notify_struct
|
||||||
|
jmp wait_for_link_down
|
||||||
|
|
||||||
|
|
||||||
try_dhcp:
|
try_dhcp:
|
||||||
|
|
||||||
DEBUGF 2,"Trying to contact DHCP server\n"
|
DEBUGF 2,"Trying to contact DHCP server\n"
|
||||||
|
|
||||||
|
mcall 40, EVM_STACK
|
||||||
|
|
||||||
mcall 75, 0, AF_INET4, SOCK_DGRAM, 0 ; open socket (parameters: domain, type, reserved)
|
mcall 75, 0, AF_INET4, SOCK_DGRAM, 0 ; open socket (parameters: domain, type, reserved)
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je error
|
je socket_error
|
||||||
mov [socketNum], eax
|
mov [socketNum], eax
|
||||||
|
|
||||||
DEBUGF 1,"Socket %x opened\n", eax
|
DEBUGF 1,"Socket %x opened\n", eax
|
||||||
|
|
||||||
mcall 75, 2, [socketNum], sockaddr1, 18 ; bind socket to local port 68
|
mcall 75, 2, [socketNum], sockaddr1, 18 ; bind socket to local port 68
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je error
|
je socket_error
|
||||||
|
|
||||||
DEBUGF 1,"Socket Bound to local port 68\n"
|
DEBUGF 1,"Socket Bound to local port 68\n"
|
||||||
|
|
||||||
mcall 75, 4, [socketNum], sockaddr2, 18 ; connect to 255.255.255.255 on port 67
|
mcall 75, 4, [socketNum], sockaddr2, 18 ; connect to 255.255.255.255 on port 67
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je error
|
je socket_error
|
||||||
|
|
||||||
DEBUGF 1,"Connected to 255.255.255.255 on port 67\n"
|
DEBUGF 1,"Connected to 255.255.255.255 on port 67\n"
|
||||||
|
|
||||||
@ -242,18 +213,16 @@ build_request: ; Creates a DHCP request
|
|||||||
DEBUGF 1,"Building request\n"
|
DEBUGF 1,"Building request\n"
|
||||||
|
|
||||||
stdcall mem.Alloc, BUFFER
|
stdcall mem.Alloc, BUFFER
|
||||||
mov [dhcpMsg], eax
|
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz dhcp_error
|
jz dhcp_fail2
|
||||||
|
mov [dhcpMsg], eax
|
||||||
;;; todo: skip this bullcrap
|
|
||||||
|
|
||||||
mov edi, eax
|
mov edi, eax
|
||||||
mov ecx, BUFFER
|
mov ecx, BUFFER
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
rep stosb
|
rep stosb
|
||||||
|
|
||||||
;; todo: put this in a buffer instead of writing bytes and words!
|
;; todo: put this in one buffer we can copy, instead of writing bytes and words!
|
||||||
|
|
||||||
mov edx, [dhcpMsg]
|
mov edx, [dhcpMsg]
|
||||||
|
|
||||||
@ -261,7 +230,7 @@ build_request: ; Creates a DHCP request
|
|||||||
mov [edx], byte 0x01 ; Boot request
|
mov [edx], byte 0x01 ; Boot request
|
||||||
mov [edx+1], byte 0x01 ; Ethernet
|
mov [edx+1], byte 0x01 ; Ethernet
|
||||||
mov [edx+2], byte 0x06 ; Ethernet h/w len
|
mov [edx+2], byte 0x06 ; Ethernet h/w len
|
||||||
mov [edx+4], dword 0x11223344 ; xid ;;;;;;;
|
mov [edx+4], dword 0x11223344 ; xid ;;;;;;; FIXME
|
||||||
mov eax, [currTime]
|
mov eax, [currTime]
|
||||||
mov [edx+8], eax ; secs, our uptime
|
mov [edx+8], eax ; secs, our uptime
|
||||||
mov [edx+10], byte 0x80 ; broadcast flag set
|
mov [edx+10], byte 0x80 ; broadcast flag set
|
||||||
@ -308,7 +277,7 @@ send_dhcpmsg:
|
|||||||
add eax, TIMEOUT*100
|
add eax, TIMEOUT*100
|
||||||
mov [timeout], eax
|
mov [timeout], eax
|
||||||
.wait:
|
.wait:
|
||||||
mcall 23, TIMEOUT ; wait for data
|
mcall 23, TIMEOUT ; wait for data (with timeout)
|
||||||
|
|
||||||
read_data: ; we have data - this will be the response
|
read_data: ; we have data - this will be the response
|
||||||
mcall 75, 7, [socketNum], [dhcpMsg], BUFFER, MSG_DONTWAIT ; read data from socket
|
mcall 75, 7, [socketNum], [dhcpMsg], BUFFER, MSG_DONTWAIT ; read data from socket
|
||||||
@ -322,7 +291,7 @@ read_data: ; we hav
|
|||||||
DEBUGF 2,"No answer from DHCP server\n"
|
DEBUGF 2,"No answer from DHCP server\n"
|
||||||
dec [tries]
|
dec [tries]
|
||||||
jnz send_dhcpmsg ; try again
|
jnz send_dhcpmsg ; try again
|
||||||
jmp dhcp_error ; fail
|
jmp dhcp_fail
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
DEBUGF 1,"%d bytes received\n", eax
|
DEBUGF 1,"%d bytes received\n", eax
|
||||||
@ -344,19 +313,15 @@ read_data: ; we hav
|
|||||||
cmp [dhcpMsgType], 0x03 ; did we send a request?
|
cmp [dhcpMsgType], 0x03 ; did we send a request?
|
||||||
je request
|
je request
|
||||||
|
|
||||||
call dhcp_end ; we should never reach here ;)
|
; we should never reach here ;)
|
||||||
jmp exit
|
jmp fail
|
||||||
|
|
||||||
discover:
|
discover:
|
||||||
call parse_response
|
call parse_response
|
||||||
|
|
||||||
cmp [dhcpMsgType2], 0x02 ; Was the response an offer?
|
cmp [dhcpMsgType2], 0x02 ; Was the response an offer?
|
||||||
je send_request
|
jne dhcp_fail
|
||||||
|
|
||||||
call dhcp_end
|
|
||||||
jmp link_local
|
|
||||||
|
|
||||||
send_request:
|
|
||||||
DEBUGF 1, "Got offer, making request\n"
|
DEBUGF 1, "Got offer, making request\n"
|
||||||
mov [dhcpMsgType], 0x03 ; make it a request
|
mov [dhcpMsgType], 0x03 ; make it a request
|
||||||
jmp build_request
|
jmp build_request
|
||||||
@ -367,11 +332,11 @@ request:
|
|||||||
cmp [dhcpMsgType2], 0x05 ; Was the response an ACK? It should be
|
cmp [dhcpMsgType2], 0x05 ; Was the response an ACK? It should be
|
||||||
jne read_data ; NO - read next packets
|
jne read_data ; NO - read next packets
|
||||||
|
|
||||||
DEBUGF 2, "Setting IP using DHCP\n"
|
DEBUGF 2, "IP assigned by DHCP server successfully\n"
|
||||||
|
|
||||||
mov [notify_struct.msg], str_connected
|
mov [notify_struct.msg], str_connected
|
||||||
mcall 70, notify_struct
|
mcall 70, notify_struct
|
||||||
call dhcp_end
|
call dhcp_fail
|
||||||
|
|
||||||
mov ebx, API_IPv4 + 3
|
mov ebx, API_IPv4 + 3
|
||||||
mov bh, [device]
|
mov bh, [device]
|
||||||
@ -383,13 +348,8 @@ request:
|
|||||||
mov bl, 9
|
mov bl, 9
|
||||||
mcall 76, , [dhcp.gateway] ; gateway
|
mcall 76, , [dhcp.gateway] ; gateway
|
||||||
|
|
||||||
jmp exit
|
jmp wait_for_link_down
|
||||||
|
|
||||||
dhcp_end:
|
|
||||||
mcall close, [socketNum]
|
|
||||||
stdcall mem.Free, [dhcpMsg]
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
;***************************************************************************
|
;***************************************************************************
|
||||||
; Function
|
; Function
|
||||||
@ -481,7 +441,7 @@ parse_response:
|
|||||||
mov eax,[edx]
|
mov eax,[edx]
|
||||||
bswap eax
|
bswap eax
|
||||||
mov [dhcpLease],eax
|
mov [dhcpLease],eax
|
||||||
DEBUGF 1,"lease: %d\n",eax
|
DEBUGF 1,"Lease: %d\n",eax
|
||||||
popa
|
popa
|
||||||
jmp .next_option
|
jmp .next_option
|
||||||
|
|
||||||
@ -506,10 +466,13 @@ parse_response:
|
|||||||
.done:
|
.done:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
dhcp_fail:
|
||||||
|
|
||||||
|
mcall close, [socketNum]
|
||||||
|
stdcall mem.Free, [dhcpMsg]
|
||||||
|
|
||||||
dhcp_error:
|
dhcp_fail2:
|
||||||
call dhcp_end
|
DEBUGF 1,"DHCP failed\n"
|
||||||
|
|
||||||
link_local:
|
link_local:
|
||||||
call random
|
call random
|
||||||
@ -577,13 +540,13 @@ link_local:
|
|||||||
mcall 5, ANNOUNCE_INTERVAL*100
|
mcall 5, ANNOUNCE_INTERVAL*100
|
||||||
jmp announce_loop
|
jmp announce_loop
|
||||||
@@:
|
@@:
|
||||||
jmp exit
|
jmp wait_for_link_down
|
||||||
|
|
||||||
|
|
||||||
error:
|
socket_error:
|
||||||
DEBUGF 2,"Socket error\n"
|
DEBUGF 2,"Socket error\n"
|
||||||
exit: ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
|
fail:
|
||||||
DEBUGF 2,"Exiting\n"
|
DEBUGF 2,"Zeroconf failed!\n"
|
||||||
mcall -1
|
mcall -1
|
||||||
|
|
||||||
|
|
||||||
@ -600,6 +563,76 @@ random: ; Pseudo random actually
|
|||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ip_str_to_dword:
|
||||||
|
push edx
|
||||||
|
|
||||||
|
; This code validates if the query is an IP containing 4 numbers and 3 dots
|
||||||
|
|
||||||
|
xor al, al ; make al (dot count) zero
|
||||||
|
|
||||||
|
@@:
|
||||||
|
cmp byte[edx],'0' ; check if this byte is a number, if not jump to no_IP
|
||||||
|
jl no_IP ;
|
||||||
|
cmp byte[edx],'9' ;
|
||||||
|
jg no_IP ;
|
||||||
|
|
||||||
|
inc edx ; the byte was a number, so lets check the next byte
|
||||||
|
|
||||||
|
cmp byte[edx],0 ; is this byte zero? (have we reached end of query?)
|
||||||
|
jz @f ; jump to next @@ then
|
||||||
|
cmp byte[edx],':'
|
||||||
|
jz @f
|
||||||
|
|
||||||
|
cmp byte[edx],'.' ; is this byte a dot?
|
||||||
|
jne @r ; if not, jump to previous @@
|
||||||
|
|
||||||
|
inc al ; the byte was a dot so increment al(dot count)
|
||||||
|
inc edx ; next byte
|
||||||
|
jmp @r ; lets check for numbers again (jump to previous @@)
|
||||||
|
|
||||||
|
@@: ; we reach this when end of query reached
|
||||||
|
cmp al,3 ; check if there where 3 dots
|
||||||
|
jnz no_IP ; if not, jump to no_IP
|
||||||
|
|
||||||
|
; The following code will convert this IP into a dword and output it in eax
|
||||||
|
; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1
|
||||||
|
|
||||||
|
pop esi ; edx (query address) was pushed onto stack and is now popped in esi
|
||||||
|
|
||||||
|
xor edx, edx ; result
|
||||||
|
xor eax, eax ; current character
|
||||||
|
xor ebx, ebx ; current byte
|
||||||
|
|
||||||
|
.outer_loop:
|
||||||
|
shl edx, 8
|
||||||
|
add edx, ebx
|
||||||
|
xor ebx, ebx
|
||||||
|
.inner_loop:
|
||||||
|
lodsb
|
||||||
|
test eax, eax
|
||||||
|
jz .finish
|
||||||
|
cmp al, '.'
|
||||||
|
jz .outer_loop
|
||||||
|
sub eax, '0'
|
||||||
|
imul ebx, 10
|
||||||
|
add ebx, eax
|
||||||
|
jmp .inner_loop
|
||||||
|
.finish:
|
||||||
|
shl edx, 8
|
||||||
|
add edx, ebx
|
||||||
|
|
||||||
|
bswap edx ; we want little endian order
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
no_IP:
|
||||||
|
pop edx
|
||||||
|
xor edx, edx
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
; DATA AREA
|
; DATA AREA
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
|
Loading…
Reference in New Issue
Block a user