Convert an ip address to long value

R

RSoIsCaIrLiIoA

I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

do you like my last try?

; nasmw -f obj this_file.asm
; bcc32 this_file.obj

section _DATA public align=4 class=DATA use32

Scrivi_numero_ip db "Srivi un internet adr. > " , 0
Errore db "Errore" , 10 , 0
Errore1 db "Errore" , 0
Errore_linea_troppo_lunga db "Errore linea troppo lunga" , 0
Numero_naturale_conversione_$u
db "Numero naturale conversione %u" , 10 , 0
Errore_contenuto_linea db "Errore contenuto linea" , 10 , 0

$lf db "%lf" , 0
errno_u_$i db "errno=%i " , 0
$u_$u db " <%u %u> " , 0
$i_p$i_p$i_p$i db " %d.%d.%d.%d%*[^" , 10 , "]" , 0
val db 0

extern _printf , _errno , _sscanf , _fgets
extern _perror , __streams , _isspace
global _main

section _TEXT public align=1 class=CODE use32

; unsigned decarr_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
decarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
..a0:
mov dl, [esi]
..a1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a4
cmp edx, 10
je .a4
cmp edx, '.'
je .a4
jmp short .e0

..a2:
lea ebx, [4*eax+eax]
sub edx, '0'
lea eax, [2*ebx]
add eax, edx
inc esi
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a4
cmp dl, 0
je .a4
mov dl, [esi]
cmp edx, '9'
jg .a4
cmp edx, '0'
jl .a4
jmp short .e0
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret

; unsigned hexarr_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
hexarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
cmp byte[esi], 'x'
je .h0
cmp byte[esi], 'X'
je .h0
jmp .e0
..h0:
inc esi
..a0:
mov dl, [esi]
..a1:
cmp edx, 'F'
ja .c0
cmp edx, 'A'
jb .c0
sub edx, 'A'
add edx, 10
jmp short .a2
..c0:
cmp edx, 'f'
ja .c1
cmp edx, 'a'
jb .c1
sub edx, 'a'
add edx, 10
jmp short .a2
..c1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
sub edx, '0'
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a6
cmp edx, 10
je .a6
cmp edx, '.'
je .a6
jmp short .e0
..a2:
shl eax, 4
inc esi
add eax, edx
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a6
cmp dl, 0
je .a6
mov dl, [esi]
cmp edx, 'F'
jg .a4
cmp edx, 'A'
jl .a4
jmp short .e0
..a4:
cmp edx, 'f'
jg .a5
cmp edx, 'a'
jl .a5
jmp short .e0
..a5:
cmp edx, '9'
jg .a6
cmp edx, '0'
jge .a6
jmp .e0

..a6:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret


; ip_to_ul(dword* ris, dword* arr)
; k=0k, 4Ra, 8ris, 12arr
ip_to_ul:
push ebp
mov ebp, esp ; @w
sub esp, 32 ; 21..24 <32
push ebx
push ecx
push edx
push esi
push edi
%define @ris ebp+8
%define @arr ebp+12
%define @w ebp+24
mov esi, [@arr]
xor ebx, ebx
jmp short .c1
..c0:
inc esi
..c1:
mov bl, [esi]
push ebx
call _isspace
add esp, 4
cmp eax, 0
jne .c0

cmp bl, 0
jne .c2
..e0:
mov eax, [@ris]
mov dword[eax], 0
jmp .fn
..c2: ; c=1.2.3.4
mov ecx, 4
mov edx, 0
mov ebx, 0
..c3:
lea eax, [@w]
push esi
push eax
call decarr_to_u
add esp, 8
cmp esi, [@w]
jne .c4
lea eax, [@w]
push esi
push eax
call hexarr_to_u
add esp, 8
cmp esi, [@w]
je .e0

..c4:
cmp eax, 255
ja .e0
shl ebx, 8
mov esi, [@w]
add ebx, eax
cmp ecx, 1
je .c5
cmp byte[esi], '.'
jne .e0
jmp short .c6
..c5:
cmp byte[esi], ' '
je .c7
cmp byte[esi], 10
je .c7
jmp short .e0
..c6:
inc esi
dec ecx
jmp short .c3
..c7:
mov eax, [@ris]
mov dword[eax], 1
mov eax, ebx
..fn:
%undef @ris
%undef @arr
%undef @w
pop edi
pop esi
pop edx
pop ecx
pop ebx
mov esp, ebp
pop ebp
ret


; k= 0k, 4Ra, 8@argc, 12@argv
_main: ; foo[256], sp[4], w[4]
push ebp ; 11..266, 267..270, 271..274<512
mov ebp, esp
sub esp, 512
push ebx
push esi
push edi
%define @argc ebp+8
%define @argv ebp+12
%define @foo ebp-266
%define @w ebp-274
mov eax, 0
mov ebx, ebp
..l0:
mov byte[ebx], 0
inc eax
dec ebx
cmp eax, 400
jb .l0
..a0:
push Scrivi_numero_ip
call _printf
add esp, 4
lea eax, [@foo]
push __streams
push 256
push eax
call _fgets
add esp, 12
cmp eax, 0
jne .l4
..l1:
push Errore
call _printf
add esp, 4
jmp .fine
..l2:
push Errore_linea_troppo_lunga
call _printf
add esp, 4
jmp .fine
..l3:
push Errore_contenuto_linea
call _printf
add esp, 4
jmp .fine
..l4:
cmp byte[eax+254], 0
jne .l2
lea ebx, [@w]
push eax
push ebx
call ip_to_ul
add esp, 8
cmp dword[@w], 0
je .l3
cmp eax, 0
je .fine
push eax
push Numero_naturale_conversione_$u
call _printf
add esp, 8
jmp .l0
..fine:
mov eax, 0
%undef @argc
%undef @argv
%undef @foo
%undef @w
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
 
R

RSoIsCaIrLiIoA

do you like my last try?

i add octal (i don't know if it is right it is the first time i write
something in 'octal')

; nasmw -f obj this_file.asm
; bcc32 this_file.obj

section _DATA public align=4 class=DATA use32

Scrivi_numero_ip db "Srivi un internet adr. > " , 0
Errore db "Errore" , 10 , 0
Errore1 db "Errore" , 0
Errore_linea_troppo_lunga db "Errore linea troppo lunga" , 0
Numero_naturale_conversione_$u
db "Numero naturale conversione %u" , 10 , 0
Errore_contenuto_linea db "Errore contenuto linea" , 10 , 0

$lf db "%lf" , 0
errno_u_$i db "errno=%i " , 0
$u_$u db " <%u %u> " , 0
$i_p$i_p$i_p$i db " %d.%d.%d.%d%*[^" , 10 , "]" , 0
val db 0

extern _printf , _errno , _sscanf , _fgets
extern _perror , __streams , _isspace
global _main

section _TEXT public align=1 class=CODE use32


; unsigned otto_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
otto_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
cmp byte[esi], ' '
jne .b1
..b0:
mov eax, 0
jmp .a4
..b1:
cmp byte[esi], 10
je .b0
cmp byte[esi], 0
je .b0
cmp byte[esi], '.'
je .b0
..a0:
mov dl, [esi]
..a1:
cmp edx, '7'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a4
cmp edx, 10
je .a4
cmp edx, '.'
je .a4
cmp edx, 0
je .a4
jmp short .e0

..a2:
shl eax, 3
sub edx, '0'
add eax, edx
inc esi
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a4
cmp dl, 0
je .a4
mov dl, [esi]
cmp edx, '7'
jg .a4
cmp edx, '0'
jl .a4
jmp short .e0
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret



; unsigned decarr_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
decarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
..a0:
mov dl, [esi]
..a1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a4
cmp edx, 0
je .a4
cmp edx, 10
je .a4
cmp edx, '.'
je .a4
jmp short .e0

..a2:
lea ebx, [4*eax+eax]
sub edx, '0'
lea eax, [2*ebx]
add eax, edx
inc esi
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a4
cmp dl, 0
je .a4
mov dl, [esi]
cmp edx, '9'
jg .a4
cmp edx, '0'
jl .a4
jmp short .e0
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret

; unsigned hexarr_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
hexarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
cmp byte[esi], 'x'
je .h0
cmp byte[esi], 'X'
je .h0
jmp .e0
..h0:
inc esi
..a0:
mov dl, [esi]
..a1:
cmp edx, 'F'
ja .c0
cmp edx, 'A'
jb .c0
sub edx, 'A'
add edx, 10
jmp short .a2
..c0:
cmp edx, 'f'
ja .c1
cmp edx, 'a'
jb .c1
sub edx, 'a'
add edx, 10
jmp short .a2
..c1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
sub edx, '0'
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a6
cmp edx, 0
je .a6
cmp edx, 10
je .a6
cmp edx, '.'
je .a6
jmp short .e0
..a2:
shl eax, 4
inc esi
add eax, edx
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a6
cmp dl, 0
je .a6
mov dl, [esi]
cmp edx, 'F'
jg .a4
cmp edx, 'A'
jl .a4
jmp short .e0
..a4:
cmp edx, 'f'
jg .a5
cmp edx, 'a'
jl .a5
jmp short .e0
..a5:
cmp edx, '9'
jg .a6
cmp edx, '0'
jge .a6
jmp .e0

..a6:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret


; ip_to_ul(dword* ris, dword* arr)
; k=0k, 4Ra, 8ris, 12arr
ip_to_ul:
push ebp
mov ebp, esp ; @w
sub esp, 32 ; 21..24 <32
push ebx
push ecx
push edx
push esi
push edi
%define @ris ebp+8
%define @arr ebp+12
%define @w ebp+24
mov esi, [@arr]
xor ebx, ebx
jmp short .c1
..c0:
inc esi
..c1:
mov bl, [esi]
push ebx
call _isspace
add esp, 4
cmp eax, 0
jne .c0

cmp bl, 0
jne .c2
..e0:
mov eax, [@ris]
mov dword[eax], 0
jmp .fn
..c2: ; c=1.2.3.4
mov ecx, 4
mov edx, 0
mov ebx, 0
..c3:
cmp byte[esi], '0'
jne .b0
cmp byte[esi+1], 'x'
je .a1
cmp byte[esi+1], 'X'
jne .a2
..a1:
lea eax, [@w]
push esi
push eax
call hexarr_to_u
add esp, 8
jmp short .c4
..a2:
lea eax, [@w]
push esi
push eax
call otto_to_u
add esp, 8
jmp short .c4
..b0:
lea eax, [@w]
push esi
push eax
call decarr_to_u
add esp, 8
..c4:
cmp esi, [@w]
je .e0
cmp eax, 255
ja .e0
shl ebx, 8
mov esi, [@w]
add ebx, eax
cmp ecx, 1
je .c5
cmp byte[esi], '.'
jne .e0
jmp short .c6
..c5:
cmp byte[esi], ' '
je .c7
cmp byte[esi], 10
je .c7
jmp .e0
..c6:
inc esi
dec ecx
jmp short .c3
..c7:
mov eax, [@ris]
mov dword[eax], 1
mov eax, ebx
..fn:
%undef @ris
%undef @arr
%undef @w
pop edi
pop esi
pop edx
pop ecx
pop ebx
mov esp, ebp
pop ebp
ret


; k= 0k, 4Ra, 8@argc, 12@argv
_main: ; foo[256], sp[4], w[4]

push ebp ; 11..266, 267..270, 271..274<512
mov ebp, esp
sub esp, 512
push ebx
push esi
push edi
%define @argc ebp+8
%define @argv ebp+12
%define @foo ebp-266
%define @w ebp-274
mov eax, 0
mov ebx, ebp
..l0:
mov byte[ebx], 0
inc eax
dec ebx
cmp eax, 400
jb .l0
..a0:
push Scrivi_numero_ip
call _printf
add esp, 4
lea eax, [@foo]
push __streams
push 256
push eax
call _fgets
add esp, 12
cmp eax, 0
jne .l4
..l1:
push Errore
call _printf
add esp, 4
jmp .fine
..l2:
push Errore_linea_troppo_lunga
call _printf
add esp, 4
jmp .fine
..l3:
push Errore_contenuto_linea
call _printf
add esp, 4
jmp .fine
..l4:
cmp byte[eax+254], 0
jne .l2
lea ebx, [@w]
push eax
push ebx
call ip_to_ul
add esp, 8
cmp dword[@w], 0
je .l3
cmp eax, 0
je .fine
push eax
push Numero_naturale_conversione_$u
call _printf
add esp, 8
jmp .l0
..fine:
mov eax, 0
%undef @argc
%undef @argv
%undef @foo
%undef @w
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
 
H

Herbert Kleebauer

RSoIsCaIrLiIoA said:
do you like my last try?


Do you want to convert a string like "137.193.64.130" into a 32 bit value
stored in a register (eax)? And for this you need more than 350 line of
code?

00000000: be 00000051 move.l #text,r5
00000005: e8 00000005 bsr.l convert ; result in eax
0000000a: e9 00000051 br.l exit

convert:
0000000f: b3 03 move.b #3,r3
00000011: 31 d2 _30: eor.l r1,r1
00000013: 31 c0 _20: eor.l r0,r0
00000015: 8a 06 move.b (r5),r0
00000017: 46 inc.l r5
00000018: 08 c0 or.b r0,r0
0000001a: 74 25 beq.b _100
0000001c: 3c 2e cmp.b #'.',r0
0000001e: 74 17 beq.b _10
00000020: 2c 30 sub.b #'0',r0
00000022: 72 2b bcs.b _error
00000024: 3c 09 cmp.b #9,r0
00000026: 77 27 bhi.b _error
00000028: 6b d2 0a mulsq.l #10,r1,r1
0000002b: 01 c2 add.l r0,r1
0000002d: 81 fa 000000ff cmp.l #255,r1
00000033: 77 1a bhi.b _error
00000035: eb dc br.b _20
00000037: fe cb _10: dec.b r3
00000039: 72 14 bcs.b _error
0000003b: 0f ac d1 08 dsr.l #8,r1>r2
0000003f: eb d0 br.b _30
00000041: 08 db _100: or.b r3,r3
00000043: 75 0a bne.b _error
00000045: 0f ac d1 08 dsr.l #8,r1>r2
00000049: 0f c9 bswap.l r2
0000004b: 89 c8 move.l r2,r0
0000004d: f8 bclr.l #0,sr
0000004e: c3 rts.l
0000004f: f9 _error: bset.l #0,sr
00000050: c3 rts.l

00000051: 31 33 37 2e 31 39
00000057: 33 2e 36 34 2e 31
0000005d: 33 30 00 text: dc.b "137.193.64.130",0
 
K

Keith Thompson

Herbert Kleebauer said:
RSoIsCaIrLiIoA wrote: [snip]
do you like my last try?

Do you want to convert a string like "137.193.64.130" into a 32 bit value
stored in a register (eax)? And for this you need more than 350 line of
code?

00000000: be 00000051 move.l #text,r5
00000005: e8 00000005 bsr.l convert ; result in eax
0000000a: e9 00000051 br.l exit
[snip]

To the folks in alt.lang.asm:

"RSoIsCaIrLiIoA" is a troll, deliberately posting assembly language to
comp.lang.c. I don't know whether what he/she writes makes sense in
the context of alt.lang.asm, but if you post a followup, *please* drop
the cross-post to comp.lang.c.

Thank you.
 
M

Mark McIntyre

do you like my last try?

I don't like any of your tries - you're posting what looks like some
form of assembler to comp.lang.c. Stop that please.
Mark McIntyre
 
J

Joe Wright

Mark said:
I don't like any of your tries - you're posting what looks like some
form of assembler to comp.lang.c. Stop that please.
Mark McIntyre

I hate to be late. Assuming this was ever a valid question, how about
this? Is there a better way?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned long
iptoul(char *ip) {
unsigned long ul = 0, t;
char *p;

do {
t = strtoul(ip, &p, 0);
ul = ul * 256 + t;
ip = p + 1;
} while (*p == '.');

return ul;
}

char *
ultoip(unsigned long ul) {
static char ip[16];
char t[16];
char *tp;
unsigned long tl;
ip[0] = '\0';

do {
tp = t;
tl = ul % 256;
ul /= 256;
if (ul) *t = '.', ++tp;
sprintf(tp, "%lu", tl);
strcat(t, ip);
strcpy(ip, t);
} while (ul);

return ip;
}

int
main(int argc, char *argv[]) {
char *ip;
unsigned long ul;
if (argc > 1)
ip = argv[1];
else
ip = "1.2.3.4";
ul = iptoul(ip);
printf("%lu, %08x\n", ul, (unsigned)ul);
puts(ultoip(ul));
return 0;
}

The theory is that really well written stuff doesn't need comments. :)
 
J

John F

Joe Wright said:
I hate to be late. Assuming this was ever a valid question, how about
this? Is there a better way?

there sure is a shorter way... It is up to you to figure out the converse
function of iptol yourself (aka ltoip)... try using the % operator and
shifting... ;-)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

<SNIP>

Too many #includes... tend to bloat the code ...

Here is my working example (OW1.4 but I don't find any implementation
defined stuff in it so it _is_ portable, AFAICS) which doesn't even need
_any_ lib-function for the logic, it is pure C too...:

//just for printf in main() and nothing else...
#include <stdio.h>

unsigned long iptol(char* IP) {
char* runner=IP;
unsigned int factor=1;
unsigned long temp=0;
unsigned int reset=0;

while(*runner) runner++;

while((IP - runner--)) {
if(*runner=='.') {
factor <<= 8;
reset^=reset;
runner--;
}
temp += factor * (*runner - '0') * (reset==1?10:(reset==2?100:1));
reset++;
}
return temp;
}

int main(int argc, char **argv)
{
if(argc<=1){
printf("Example: %s 10.2.3.123\n", argv[0]);
return -1;
}

printf("%x:%ld",iptol(argv[1]),iptol(argv[1]));
return 0;
}
The theory is that really well written stuff doesn't need comments. :)

could be true :) but I tend to say real beauty needs no decoration...

regards
John
 
J

John F

John F said:
Here is my working example (OW1.4 but I don't find any implementation
defined stuff in it so it _is_ portable, AFAICS) which doesn't even need
_any_ lib-function for the logic, it is pure C too...:

the portability stuff was meant to exclude the argv[0] ... sorry...
if(argc<=1){
printf("Example: %s 10.2.3.123\n", argv[0]);
return -1;
}

this is of course _not_ portable... I simply read over it... sorry.

regards
John
 
C

CBFalconer

Mark said:
I don't like any of your tries - you're posting what looks like some
form of assembler to comp.lang.c. Stop that please.

+-------------------+ .:\:\:/:/:.
| PLEASE DO NOT F :.:\:\:/:/:.:
| FEED THE TROLLS | :=.' - - '.=:
| | '=(\ 9 9 /)='
| Thank you, | ( (_) )
| Management | /`-vvv-'\
+-------------------+ / \
| | @@@ / /|,,,,,|\ \
| | @@@ /_// /^\ \\_\
@x@@x@ | | |/ WW( ( ) )WW
\||||/ | | \| __\,,\ /,,/__
\||/ | | | jgs (______Y______)
/\/\/\/\/\/\/\/\//\/\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
==============================================================

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
 
P

Phil Carmody

John F said:
reset^=reset;

Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0
?

Or do you just think that more is more?

Phil
 
J

John Bode

kyle.tk said:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

[snip]


Any suggestions? Maybe there is a better way to do this?

-kyle

This example is probably a little silly, but it has the advantage of
not relying on the standard library (other than printf()). It will
handle octets in different formats (e.g., 0.255.0377.0xff) and it will
accept leading and trailing whitespace in each octet (e.g., "127. 0
..0. 1"). Whitespace embedded within the octet token ("1 27.0.0.1")
will cause the function to return 0.

Error handling is non-existent; it will not detect overflow in any of
the octets (e.g. 256.397.400.999), nor will it handle missing octets
(255.255.0). That should be relatively straightforward to fix, though.

#include <stdio.h>

typedef enum {start, lead, dec, oct, hex, tail, err} state_t;
typedef enum {shft, eval, none} action_t;

static state_t stateTable[7][20] = {
{lead, dec, dec, dec, dec, dec, dec, dec, dec, dec, err, err, err,
err, err, err, err, err, start, err},
{oct, oct, oct, oct, oct, oct, oct, oct, err, err, err, err, err,
err, err, err, hex, start, tail, err},
{dec, dec, dec, dec, dec, dec, dec, dec, dec, dec, err, err, err,
err, err, err, err, start, tail, err},
{oct, oct, oct, oct, oct, oct, oct, oct, err, err, err, err, err,
err, err, err, err, start, tail, err},
{hex, hex, hex, hex, hex, hex, hex, hex, hex, hex, hex, hex, hex,
hex, hex, hex, err, start, tail, err},
{err, err, err, err, err, err, err, err, err, err, err, err, err,
err, err, err, err, start, tail, err},
{err, err, err, err, err, err, err, err, err, err, err, err, err,
err, err, err, err, err, err, err}
};

static action_t actionTable[7][20] = {
{none, shft, shft, shft, shft, shft, shft, shft, shft, shft, none,
none, none, none, none, none, none, eval, none, none},
{shft, shft, shft, shft, shft, shft, shft, shft, none, none, none,
none, none, none, none, none, none, eval, none, none},
{shft, shft, shft, shft, shft, shft, shft, shft, shft, shft, none,
none, none, none, none, none, none, eval, none, none},
{shft, shft, shft, shft, shft, shft, shft, shft, none, none, none,
none, none, none, none, none, none, eval, none, none},
{shft, shft, shft, shft, shft, shft, shft, shft, shft, shft, shft,
shft, shft, shft, shft, shft, none, eval, none, none},
{none, none, none, none, none, none, none, none, none, none, none,
none, none, none, none, none, none, eval, none, none},
{none, none, none, none, none, none, none, none, none, none, none,
none, none, none, none, none, none, none, none, none}
};


static int mapchar(int c)
{
switch(c)
{
case '0': return 0; break;
case '1': return 1; break;
case '2': return 2; break;
case '3': return 3; break;
case '4': return 4; break;
case '5': return 5; break;
case '6': return 6; break;
case '7': return 7; break;
case '8': return 8; break;
case '9': return 9; break;
case 'a': case 'A': return 10; break;
case 'b': case 'B': return 11; break;
case 'c': case 'C': return 12; break;
case 'd': case 'D': return 13; break;
case 'e': case 'E': return 14; break;
case 'f': case 'F': return 15; break;
case 'x': case 'X': return 16; break;
case '.': case 0: return 17; break;
case ' ': case '\t': case '\n': return 18; break;
default: return 19;
}
}

unsigned long iptolong(const char *ip)
{
unsigned long ipval=0;
unsigned long octet=0;
int base=10;

state_t state = start;
do
{
action_t action = actionTable[state][mapchar(*ip)];
switch(action)
{
case shft:
octet = octet * base + mapchar(*ip);
break;

case eval:
ipval <<= 8;
ipval += octet;
octet = 0;
break;

default:
break;
}

state = stateTable[state][mapchar(*ip)];
switch(state)
{
case dec: base = 10; break;
case oct: base = 8; break;
case hex: base = 16; break;
}
} while(*ip++);

return ipval;

}

int main(int argc, char **argv)
{
unsigned long ipval;
ipval = iptolong(argv[1]);
printf("long value of \"%s\" is %lu (%x)\n", argv[1], ipval,
ipval);

return 0;
}
 
J

John F

Phil Carmody said:
Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0

maybe... depends on the optimizer... That way I encourage the optimizer into

mine does generate two 3 byte instructions...
mov eax, dword ptr -0x4[ebp]
xor dword ptr -0x4[ebp],eax

versus one seven byte instruction...
mov dword ptr -0x4[ebp],0x00000000
Or do you just think that more is more?

not always :) depends on the object...

regards
John F(dot)
 
J

Jordan Abel

Phil Carmody said:
Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0

maybe... depends on the optimizer... That way I encourage the optimizer into

mine does generate two 3 byte instructions...
mov eax, dword ptr -0x4[ebp]
xor dword ptr -0x4[ebp],eax

versus one seven byte instruction...
mov dword ptr -0x4[ebp],0x00000000

How about just passing -Os [or whatever "optimize for size" option] to
the compiler and letting it make that decision? Your "two 3 byte
instructions" also waste a register, and probably take twice as long to
execute, if not longer
 
J

John F

Jordan Abel said:
Phil Carmody said:
:
reset^=reset;

Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0

maybe... depends on the optimizer... That way I encourage the optimizer
into

mine does generate two 3 byte instructions...
mov eax, dword ptr -0x4[ebp]
xor dword ptr -0x4[ebp],eax

versus one seven byte instruction...
mov dword ptr -0x4[ebp],0x00000000

How about just passing -Os [or whatever "optimize for size" option] to
the compiler and letting it make that decision?

-Os is OW ... it doesn't make the decision to translate =0 with x^x ...
There seems to be slight a difference in the semantics tree ... dunno. Have
to dig into that :) quite interesting why ... or rather why not.
Your "two 3 byte
instructions" also waste a register, and probably take twice as long to
execute, if not longer

BC3.1 does generate xor cx,cx ... that's simple and fast... it will depent
largely on the instruction set that is used.
I'll ask an OW expert how to get the compiler to use ecx ... since it gets
push/pop-ed ... weird stuff.

regards
John
 
J

John Bode

John Bode wrote:
[snip]
Whitespace embedded within the octet token ("1 27.0.0.1")
will cause the function to return 0.

=sigh=

Actually, that's not true. I was thinking of a slightly different
version of this code that I was working on before settling on this
solution. What you should get back in this case is the value of
whatever octets have been processed up to this point.

Again, no error handling in this version.
 
J

Jordan Abel

Jordan Abel said:
:
:
reset^=reset;

Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0

maybe... depends on the optimizer... That way I encourage the optimizer
into

mine does generate two 3 byte instructions...
mov eax, dword ptr -0x4[ebp]
xor dword ptr -0x4[ebp],eax

versus one seven byte instruction...
mov dword ptr -0x4[ebp],0x00000000

How about just passing -Os [or whatever "optimize for size" option] to
the compiler and letting it make that decision?

-Os is OW ... it doesn't make the decision to translate =0 with x^x ...
There seems to be slight a difference in the semantics tree ... dunno. Have
to dig into that :) quite interesting why ... or rather why not.
Your "two 3 byte
instructions" also waste a register, and probably take twice as long to
execute, if not longer

BC3.1 does generate xor cx,cx ... that's simple and fast... it will depent
largely on the instruction set that is used.

The problem is that your variable is in memory, so storing an 0 literal
to it is faster than the "xor trick"
I'll ask an OW expert how to get the compiler to use ecx ... since it gets
push/pop-ed ... weird stuff.

It sounds like you don't really understand asm
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top