Re: my first .dll: why doesn't it work ...
From: Ro (inp_out_at_sim.tim)
Date: 11/29/04
- Next message: Betov: "Re: my first .dll: why doesn't it work ..."
- Previous message: Ro : "Re: my first .dll: why doesn't it work ..."
- In reply to: Ro : "my first .dll: why doesn't it work ..."
- Next in thread: Betov: "Re: my first .dll: why doesn't it work ..."
- Reply: Betov: "Re: my first .dll: why doesn't it work ..."
- Reply: wolfgang kern: "Re: my first .dll: why doesn't it work ..."
- Reply: NoDot: "Re: my first .dll: why doesn't it work ..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 29 Nov 2004 09:31:54 GMT
Do you like 'my' assembly language?
/* This program is free software; you can redistribute it and/or
modify
/* it under the terms of the GNU General Public License as published
by
/* the Free Software Foundation; either version 2 of the License, or
/* (at your option) any later version.
/*
/* This program is distributed in the hope that it will be useful,
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/* GNU General Public License for more details.
/*
/* You should have received a copy of the GNU General Public License
/* along with this program; if not, write to the Free Software
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
/*
/* *Non* e' consentito usare le funzioni atou, atoi, uPrint, utoa,
/* itoa, utoh, hPrint, AsciiToSt0, converti_exp, converti, _mult10,
/* St0ToAscii, BcdToString, round, IncArray scritte qui sotto
/* per usi militari o di spionaggio o nei campi biologico (quindi
/* anche gentica), farmaceutico, nucleare
/* con a6
/* nasm -f obj prog.asm
/* alink -oPE prog.obj dlg.res
section .text use32
section .data use32
section .const use32
section .bss use32
section .text
section .data
%macro str 2+
[section .data]
align 4, db 0
%1 db %2
dd 0
__SECT__
%endmacro
%define NL 13, 10
%define STDIN -10
%define STDOUT -11
%define IDI_ICON 100
%define IDR_MENU 2000
%define IDM_RANDOM 2001
%define IDM_MAX_RANDOM 2002
%define IDM_RANGE_RANDOM 2003
%define IDM_GAUSS 2004
%define IDM_LINEARE 2007
%define IDM_LINEARE1 2008
%define IDM_EXIT 2005
%define IDM_HELP_ABOUT 2006
%define IDC_ARROW 07f00h
IDCANCEL equ 2h ;
== ReadFile, WriteFile, GetStdHandle, ExitProcess == kernel32.dll
== GetModuleHandleA, GetTickCount == kernel32.dll
== DialogBoxParamA, EndDialog, MessageBoxA, SetDlgItemTextA ==
user32.dll
== LoadIconA, LoadCursorA, RegisterClassA, LoadMenuA, ShowWindow ==
user32.dll
== CreateWindowExA, DestroyWindow, PostQuitMessage, UpdateWindow ==
user32.dll
== TranslateMessage, DispatchMessageA, GetMessageA ==
user32.dll
== DefWindowProcA, ReleaseDC, wsprintfA == user32.dll
== SendMessageA, GetDlgItemTextA, LoadBitmapA, BeginPaint ==
user32.dll
== GetClientRect, EndPaint, GetDC, FillRect, RedrawWindow ==
user32.dll
== CreateCompatibleDC, SelectObject, BitBlt, DeleteDC, SetPixel ==
gdi32.dll
/* se numero<=limiti => ok altrimenti e' troppo grande
base dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
seed dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
seed0 dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
numero dt -234545.4555599555555e50, 0.0, 0.0, 0.0
numero1 dt -12344444444444444444.0e5, 0.0
num_temp dt 0.0, 0.0
str_pnt dd 0
stringa db "23.85e40", 0
titolo db "Numero 80bits", 0
buffer times 512 db 0
dieci dd 10, 0
cw_data dw 0000001101111111b
align 10, db 0 /* +InF
piu_oo dd 0, 0x80000000, 0x7FFF, 0
align 10, db 0 /* -InF
meno_oo dd 0, 0x80000000, 0xffff, 0
/* 0 1 2 3 4 5
dieci_1 dt 1.0 , 10.0 , 100.0, 1000.0, 10000.0, 100000.0
dt 1.0e6 , 1.0e7, 1.0e8, 1.0e9 , 1.0e10 , 1.0e11, 1.0e12,
1.0e13
dt 1.0e14, 1.0e15
dieci_16 dt 1.0 , 1.0e16 , 1.0e32 , 1.0e48 , 1.0e64 ,
1.0e80 , 1.0e96, 1.0e112
dt 1.0e128, 1.0e144, 1.0e160, 1.0e176, 1.0e192,
1.0e208, 1.0e224, 1.0e240
dieci_256 dt 1.0 , 1.0e256 , 1.0e512 , 1.0e768 , 1.0e1024,
1.0e1280, 1.0e1536, 1.0e1792
dt 1.0e2048, 1.0e2304, 1.0e2560, 1.0e2816, 1.0e3072,
1.0e3328, 1.0e3584, 1.0e3840
dt 1.0e4096, 1.0e4352, 1.0e4608, 1.0e4864 /* 20=0..19
WM_INITDIALOG equ 0110h; WM_COMMAND equ 0111h; WM_PAINT equ
0fh;
WM_DESTROY equ 2h; WM_CLOSE equ 10h; WM_NCPAINT equ
085h ;
WM_ERASEBKGND equ 14h; WM_CTLCOLOREDIT equ 133h;
WM_MOUSEMOVE equ 200h; WM_NCMOUSEMOVE equ 0A0h;
MB_OK equ 0; MB_SYSTEMMODAL equ 01000h;
EM_SETSEL equ 0b1h; SRCCOPY equ 0cc0020h; SW_SHOW equ
5h
RDW_INVALIDATE equ 01h; RDW_INTERNALPAINT equ 02h; RDW_ERASE equ
04h
WS_EX_CLIENTEDGE equ 200h; WS_OVERLAPPEDWINDOW equ 0cf0000h;
WS_VISIBLE equ 10000000h
FirstMessage dd 0, 0, 0, 0, 0, 0, 0
struc rect1
Left resd 1 | Top resd 1 | Right resd 1
Bottom resd 1 | Stw resd 1 | Sth resd 1
endstruc
%macro rect1_fill 7
[section .data]
%1 dd %2|dd %3|dd %4|dd %5|dd %6|dd %7
__SECT__
%endm
struc WindowClass
style resd 1 | lpfnWndProc resd 1 | cbClsExtra resd 1 |
cbWndExtra resd 1
hInstance resd 1| hIcon resd 1 | hCursor resd 1 | hbrBackground
resd 1
lpszMenuName resd 1| lpszClassName resd 1
endstruc
%macro window_fill 11
[section .data]
%1 | dd %2|dd %3|dd %4|dd %5|dd %6|dd %7|dd %8|dd %9|dd %10|dd %11
__SECT__
%endm
window_fill wstr, 3, MainWindowProc, 0, 0, 0, 0, 0, 6, 0,
WindowClassName
db, WindowClassName='Anything', WindowCaption='Base App';
dd, WindowHandle=0, MenuHandle=0, WindowX=50, WindowY=50,
WindowW=500, WindowH=350;
[section .text]
..start:
{pushad
[wstr+ hInstance] = *GetModuleHandleA(0);
[wstr+ hIcon] = *LoadIconA( D[wstr+hInstance] , IDI_ICON);
[wstr+ hCursor] = *LoadCursorA( 0, IDC_ARROW);
*RegisterClassA(wstr);
*MenuHandle = *LoadMenuA( D[wstr+hInstance], IDR_MENU );
*WindowHandle = *CreateWindowExA( WS_EX_CLIENTEDGE,
WindowClassName,
WindowCaption, _ WS_OVERLAPPEDWINDOW || WS_VISIBLE _
,
D*WindowX, D*WindowY, D*WindowW,
D*WindowH,
0, D*MenuHandle, D[wstr+hInstance],
0); /* 12 argomenti
*ShowWindow( D*WindowHandle, SW_SHOW);
*UpdateWindow( D*WindowHandle );
finit; #.L1;
.While:
{*TranslateMessage(FirstMessage);
*DispatchMessageA(FirstMessage);
.L1: *GetMessageA(FirstMessage, 0, 0, 0);
a#.While
}
popad
*ExitProcess(0);
}
/* void MainWindowProc(Adr, msg, wpar, lpar)
/* 0 k, 4 Ra, 8 P_Adr, 12 P_msg, 16 P_wpar, 20 P_lpar
MainWindowProc:
{< k
k = s;
<< @Adressee=[k+8], @Message=[k+12], @wParam=[k+16], @lParam=[k+20]
/*---------------------------------------
D @Message == WM_CLOSE !#.Else_If0
{*DestroyWindow( D @Adressee ); a=1; ##.End_If; }
.Else_If0: D @Message == WM_DESTROY !#.Else_If1
{*PostQuitMessage(0); a=1; ##.End_If; }
.Else_If1: D @Message == WM_COMMAND #.cont
##.Else
.cont:
{ D @wParam == IDM_EXIT !#.Else_If2
{*SendMessageA( D @Adressee, WM_CLOSE, 0, 0);
a=1; ##.End_If}
.Else_If2: D @wParam == IDM_RANDOM !#.Else_If3
{fld T*numero; Tprinth(); a=1; ##.End_If }
.Else_If3: D @wParam == IDM_MAX_RANDOM !#.Else_If4
{fld T*numero1; Tprinth(); a=1; ##.End_If }
.Else_If4: D @wParam == IDM_RANGE_RANDOM !#.Else_If5
{AsciiToSt0(stringa, str_pnt); Tprinth(); a=1; ##.End_If }
.Else_If5: D @wParam == IDM_GAUSS !#.Else_If5a
{fld T*numero;
St0ToAscii(base, 6, 2);
fstp st0;
uPrint(base, a);
a=1; ##.End_If
}
.Else_If5a: D @wParam == IDM_LINEARE !#.Else_If5b
{a=1; ##.End_If }
.Else_If5b: D @wParam == IDM_LINEARE1 !#.Else_If6
{a=1; ##.End_If }
.Else_If6: D @wParam == IDM_HELP_ABOUT !#.End_Ifn
{a=1; ##.End_If }
.End_Ifn:
a=0; ##.End_If;
}
.Else:
{ *DefWindowProcA( D @Adressee, D @Message, D @wParam, D
@lParam); }
.End_If:
>> @Adressee, @Message, @wParam, @lParam
s = k
> k;
ret 16
}
/* eax atou(char* string, char* pos)
/* 0 i, 4 r, 8 b, 12 Ra, 16 string, 20 pos
atou:
< b, r, i
<< @string=[s+16], @pos=[s+20]
i=@string; #.c1;
.c0: ++i; .c1: B*i==' '#.c0;
B*i=='+'!#.c2 | ++i;
.c2: B*i>'9' #.ce;
B*i<'0' #.ce;
#.c4;
.ce: a=@pos; r=@string; *a=r; a=0; #.cf;
.c3: ++i; .c4: B*i=='0'#.c4
a=0; b=0;
.c5: bl=*i;
bl>'9'#.c7
bl<'0'#.c7
mul D*dieci; r#.ci;
b-='0'; a+=b; jc .ci
++i; #.c5;
.ci: a=0xFFFFFFFF;
.c6: ++i; bl=*i; bl>'9'#.c7;
bl<'0'#.c7; #.c6
.c7: r=@pos; *r=i;
.cf:
>> @string, @pos
> b, r, i
ret 8
/* eax atoi(char* string, char* pos)
/* 0 i, 4 r, 8 c, 12 b, 16 Ra, 20 string, 24 pos
atoi:
< b, c, r, i
<< @string=[s+20], @pos=[s+24]
i=@string; c=0; #.c1; /* in c il segno
.c0: ++i; .c1: B*i==' '#.c0;
B*i=='+'!#.c2 | ++i; #.c3;
.c2: B*i=='-'!#.c3 | ++i; ++c;
.c3: B*i>'9' #.ce;
B*i<'0' #.ce;
#.c5;
.ce: a=@pos; r=@string; *a=r; a=0; #.cf;
.c4: ++i; .c5: B*i=='0'#.c4
a=0; b=0;
.c6: bl=*i;
bl>'9'#.c8
bl<'0'#.c8
mul D*dieci| r#.ci /* in ci +/-oo
b-='0'; a+=b| jc .ci
a&0x80000000 | jnz .ci
++i; #.c6;
.ci: a=0x7FFFFFFF;
.c7: ++i; bl=*i; bl>'9'#.c8;
bl<'0'#.c8; #.c7
.c8: c#.c9; neg a
.c9: r=@pos; *r=i;
.cf:
>> @string, @pos
> b, c, r, i
ret 8
/* uso: str .titolo, "Numero " ; uPrint(titolo, D*num);
/* utoaz( a < char* Title, unsigned n)
/* k k= 0k, 4 Ra, 8 1P_Title, 12 1P_n
uPrint:
{< k
k = s;
pushad /* sono necessari perche messagebox sembra cambi anche
ecx!!!
s-=128;
<< @Title=[k+8], @n=[k+12], @string=[s]
/*--------------------*/
a=@n; c= & @string; utoa(c, a);
a=@Title; c= & @string;
*MessageBoxA( 0, a, c, _ MB_OK || MB_SYSTEMMODAL _ );
>> @Title, @n, @string
s+=128
popad
s = k
> k;
ret 8
}
/* eax utoa(char* string, unsigned n)
/* ritorna in eax i chiars scritti
/* 0 k, 4 j, 8 i, 12 r, 16 b, 20 Ra, 24 1P_string, 28 1P_n
utoa:
{< b, r, i, j, k
<< @string=[s+24], @n=[s+28]
/*--------------------*/
i=@string; b=10; a=@n; j=i; k=0;
.utoaz_l:
{r ^= r
div b /* a= (r:a)/b r= (r:a)%b
rl+='0'; *j=rl; ++j; ++k
a#.utoaz_l
}
B*j=0; --j | #.vai
.utoaz_f:
{al=*i; ah=*j;
*j=al; *i=ah;
++i | --j;
.vai:
i<j #.utoaz_f
}
a=k;
.utoaz_z:
>> @string, @n
> b, r, i, j, k
ret 8
}
/* eax itoa(char* string, int n)
/* ritorna in eax i chiars scritti
/* 0 k, 4 j, 8 i, 12 r, 16 b, 20 Ra, 24 1P_string, 28 1P_n
itoa:
{< b, r, i, j, k
<< @string=[s+24], @n=[s+28]
/*--------------------*/
i=@string; b=10; a=@n; k=0;
a&0x80000000; jz .c0;
neg a; B*i='-'; #.c1 /* a&0x70000000;
.c0: B*i='+';
.c1: ++i; ++k; j=i;
.itoaz_l:
{r ^= r
div b /* a= (r:a)/b r= (r:a)%b
rl+='0'; *j=rl; ++j; ++k
a#.itoaz_l
}
B*j=0; --j | #.vai
.itoaz_f:
{al=*i; ah=*j;
*j=al; *i=ah;
++i | --j;
.vai:
i<j #.itoaz_f
}
a=k;
.itoaz_z:
>> @string, @n
> b, r, i, j, k
ret 8
}
/* void utoh(char* Title, uint n)
/* scrive 8 chars in Title => 8+1'\0'=9 chars richiesti
/* 0-7 digits 8'\0' 9 caratteri in tutto
/* 0 a, 4 c, 8 b, 12 i, 16 Ra, 20 1P_Title, 24 1P_n
utoh:
{< a, c, b, i
<< @n=[s+24], @Title=[s+20]
b=@n; c=@Title; i=c; i+=7;
.l0:
{al=bl; al&=0Fh; al+='0';
al>'9'!#.l1; al+= 7;
.l1:
B*i=al; --i; b>>=4; c<=i#.l0
}
>> @n, @Title
> a, c, b, i
ret 8
}
Tprinth:
< b, a
fstp T*num_temp /* il valore in st0 e levato dallo stack
b=buffer;
utoh(b, D*num_temp ); b+=8; B*b='#'; ++b /* 32
utoh(b, D[num_temp+4]); b+=8; B*b='#'; ++b /* +32
utoh(b, D[num_temp+8]); b+=8; B*b='#'; ++b; B*b='#'; ++b /* +16
B*b=0; ++b;
*MessageBoxA( 0, buffer, titolo, _ MB_OK || MB_SYSTEMMODAL _ );
> b, a
ret
/* uso: str titolo, "Numero " ; hPrint(titolo, D*num);
/* utoaz( a < char* Title, unsigned n)
/* k= 0k, 4 Ra, 8 1P_Title, 12 1P_n
hPrint:
{< k
k = s;
pushad /* sono necessari perche messagebox sembra cambi anche ecx!!!
s-=128;
<< @Title=[k+8], @n=[k+12], @HexprintString=[s]
/*--------------------*/
a=@n; c= & @HexprintString; utoh(c, a);
a=@Title; c= & @HexprintString;
*MessageBoxA( 0, c, a, _ MB_OK || MB_SYSTEMMODAL _ );
>> @Title, @n, @HexprintString
s+=128
popad
s = k
> k;
ret 8
}
/* st0 AsciiToSt0(P_string, P_address_then);
/* se [P_address_then]==[P_string] allora st0=0 e non e' preso
altrimenti
/* il numero e' preso. Utilizza due registri dello stack-fpu
/* per k: 0 k, 4Ra, 8P_string, 12P_address
AsciiToSt0:
{< k
k = s;
< b, c, r, i, j
s-=16 /* s=0num0, 4num1, 8sign, 12cw_save
fnstcw [s+12];
fldcw [cw_data]; /* resetta tutto + troncamento
/* converti scrive nello 2 dd nello stack qui allocato
i=[k+8]; converti(); jnc .a0
a=[k+8]; b=[k+12]; *b=a; fldz; ##.cx
.a0: [s+8]=b; a=0; /* caso non errore
#.c1 /* leva gli spazi
.c0: ++j| .c1: B*j==' '#.c0;
bl=B*j;
bl=='e' #.c2 /* 44.44 e -12455
bl!='E' #.c3
.c2: converti_exp(); /* in a esponente
a> 4931 ?#.ce_piu_oo
c> 4931 ?#.ce_piu_oo
a< -4931 ?#.ce_zero
.c3: a+=c
/* uPrint(titolo, a);
a> 4931 ?#.ce_piu_oo
a< -4931 ?#.ce_zero
#.c4
.ce_piu_oo: D[s+8]==0!#.seielmeno |fld T*piu_oo |##.cq;
.seielmeno: fld T*meno_oo; ##.cq;
.ce_zero: fldz; ##.cf;
.c4: fpow10i(); /* 10^a
/fist D*nim; uPrint(titolo, D*nim);
.c5: fild Q[s]; /* num, 10^a
/fist D*nim; uPrint(titolo, D*nim);
fmulp st1 /* num*10^a
.cf: D[s+8]==0 #.cq; FCHS;
.cq: a=[k+12]; *a=j;
.cx: fldcw [s+12];
s+=16
> b, c, r, i, j
s = k
> k;
ret 8
/* <j>pos <a>num+sign converti_exp<j>
converti_exp:
< b, c, r, i, k
i=j; b=0; r=0;
.c0: ++j| B*j==' ' #.c0; /* leva gli spazi
B*j=='+'!#.c1 | ++j; #.c2
.c1: B*j=='-'!#.c2 | ++j; ++b;
.c2: B*j>'9' #.ce
B*j<'0' #.ce /* nel caso dopo eventuale + o -
#.c3
.ce: j=i; a=0; ##.cf
.c3: #.c5 /* leva gli zeri
.c4: ++j| .c5: B*j=='0' #.c4;
a=0; c=0; k=0;
.c6: cl=*j
cl<='9' !#.c8
cl>='0' !#.c8
mul D*dieci;
cl-='0'; a+=c;
a>4931#.ck
++j | #.c6;
.ck: ++j; cl=*j
cl<='9' !#.c8
cl>='0' !#.c8 | #.ck
.c8: b==1!#.cf | neg a
.cf:
> b, c, r, i, k
ret
/* input signed int a; output 10^a in st0
/* utilizza due posizioni dello fpu-stack
/* non inizializza niente; rounding mode per troncamento
/* settato all'esterno
fpow10i:
< a, b, c
a< -4931 ?#.ze
a> 4931 ?#.oo
#.c0
.ze: fldz; ##.fine
.oo: fld T*piu_oo; ##.fine
.c0: b=0; a&0x80000000 | jz .c1 | neg a | b=1
.c1: c=a; c&=0xF; c= &[c+4*c]; c= &[2*c];
FLD T[dieci_1 + c];
c=a; c>>= 4; c&=0xF; c= &[c+4*c]; c= &[2*c];
FLD T[dieci_16 + c];
c=a; c>>= 8; FMULP st1; /* ok poiche' c<=4931
c= &[c+4*c]; c= &[2*c]; /* e 4931>>8 == 19
FLD T[dieci_256 + c];
b<>1; FMULP st1; jnz .fine
FLD1 | FDIVRP st1
.fine:
> a, b, c
ret
/* segno in b
/* numero nello stack del chiamante in num1:num0 numero
/* di cifre in c, ultima posizione in j
/* nel caso di errore o nessun numero stc altrimenti clc
/* converti<origine i>
/* 0 @sign, 4k, 8r, 12 i, 16 a, 20 Ra, 24 num0, 28 num1
converti:
< a, i, r, k /* i punta sempre al carattere
/* corrente della stringa
<< @sign=[s]
s-=4
#.c1 /* leva gli spazi
.c0: ++i| .c1: B*i==' ' #.c0;
D @sign=0;
B*i=='+' !#.b0 | ++i; #.c2
.b0: B*i=='-' !#.c2 | ++i; ++D @sign;
.c2: B*i>'9' #.ce
B*i<'0' #.ce /* nel caso dopo eventuale + o -
#.b1; /* c'e' un non numero => errore
.ce: r=0; a=0; c=0; b=0; j=^12; ##.cf
.b1: #.g1 /* leva gli zeri
.g0: ++i| .g1: B*i=='0' #.g0;
a=0; r=0; k=0; j=0; c=0;
.c3: al=*i /* prende parte non esponente
al<='9' !#.c4
al>='0' !#.c4
_mult10(); jc .c7
al-='0'; k+=a | jnc .b2| ++r | jno .b2
k-=a; --r; --c #.c7
.b2: ++i| #.c3;
.c4: al=='.' #.a1 | ##.c9;
.a1: B[i+1]>'9'#.a2 | B[i+1]<'0'#.a2
#.a3
.a2: ##.c9; /* caso numero.?non_numero
.a3: j=i; /* caso numero.?numero
.ca: ++j; al=*j /* elimina gli zeri superflui
al>'9'#.cb;
al<'0'#.cb;
#.ca;
.cb: --j; al=*j | al=='0'#.cb /* j punta *all'ultimo numero* non zero
i==j!#.cd; ##.c9 /* tranne caso numero.000000000
.cd: i==j#.a0
++i; al=*i;
_mult10(); jc .a0 /* elimina i restanti decimali
al-='0'; --c; k+=a | jnc .a4; ++r | jno .a4
k-=a; --r; #.a0
.a4: #.cd;
.c7: ++c; ++i; al=*i /* caso 999etc
al<='9' !#.c8
al>='0' #.c7
.c8: al=='.' !#.c9 /* caso 999etc.etc
B[i+1]>'9'#.c9;
B[i+1]<'0'#.c9;
.a0: ++i; al=*i
al<='9' !#.c9
al>='0' #.a0
.c9: j=i; b=@sign;
.cf: s+=4
j==[s+8] !#.cc | stc | #.cz
.cc: clc /* [s+8]==i
.cz: [s+20]=k; [s+24]=r; /* nello stack la risposta
>> @sign
> a, i, r, k
ret
/* r:k mult10<r:k>
/* ma (r:k)*10< 1 0 0 ? clearCarry: setCarry
/* 0 j, 4 i, 8 c, 12 b, 16 a, 20 Ra
_mult10:
{< a, b, c, i, j
/*------------------*/
c=r; j=k; a=k; /* salva input in c:j
mul D*dieci; /* k*10
i=a; k=r; /* save result in i:k
a=c; mul D*dieci;
a+=k | jnc .m0 | ++r;
.m0:
r!=0 #.mfineset;
r=a; k=i;
r&0x80000000|jnz .mfineset
/* qui perde un bit per il segno
clc; #.mfine
.mfineset:
r=c; k=j;
stc;
.mfine:
> a, b, c, i, j
ret
}
/* eax St0ToAscii( char* string, uint intPart, uint decPart )
<st0>;
/* Suppone che la stringa sia sufficientemente ampia ritorna
/* in eax il numero di caratteri scritti usa due registri float
/* per intPart=0 scrive il numero senza esponente se l'esponente
/* permette (e<17 && e>0) altrimenti (intPart, decPart)=( 1, decPart )
/* se intPart o decPart sono fuori range li aggiusta
/* privileggiando intPart
/* k: 0k, 4 ra, 8 P_string, 12 P_intPart, 16 P_decPart
St0ToAscii:
< k
k = s
< b, c, r, i
s-=32 /* 10, 20; 0-9=num, 12-15=exp, 16-17=wc_temp 20-29=bcd
<< @string=[k+8], @exp=[s+12], @wc_temp=[s+16], @bcd=[s+20]
fnstcw @wc_temp;
D[s+8]=0;
fldcw [cw_data]; /* resetta tutto + troncamento
fxam /* controlla numero in st0 setta c0, c1, c2, c3
i=@string
fnstsw ax; /* store in ax content of stauts reg
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15
/* c0 c1 c2 c3
/* c1= sign; c3, c2, c0
/* non suppo. 0 0 0 formato
/* NaN 0 0 1
/* Finite num. 0 1 0
/* Infinity 0 1 1
/* Zero 1 0 0
/* Empty reg. 1 0 1
/* Denormal 1 1 0
al=ah;
al & 00000010b | jz .c0 | B*i='-' | #.c1
.c0: B*i='+'
.c1: ++i; al&=01000101b /* leva il bit del segno
al==00000000b!#.c2 /* in .cf nessuna operazione in fpu-stack
--i; D*i='Ns'; a=2; ##.cf
.c2: al==00000001b!#.c3
--i; D*i='NaN'; a=3; ##.cf
.c3: al==00000101b!#.c4
D*i='InF'; a=4; ##.cf
.c4: al==01000000b!#.c5
D*i='0.0'; a=4; ##.cf
.c5: al==01000001b!#.c7
--i; D*i='Nul'; a=3; ##.cf
.c6: D*i='0.0'; a=4; ##.ca
.c7: fld st0; /* st = num, num
fstp T*s; /* st = num ; salva il numero num
fxtract /* st = f(num), e(num)
fstp st0; /* st = e(num)
fldlg2 /* st = log_10(2),e(num)
fmulp st1; /* st = log_10(2)*e(num)
fistp D @exp; /* st = vuoto; salva x in 10^x, pop;
/* salva l'esponente
a = @exp; neg a; a+=17; a>4931?#.c6; /* in .c6 0.0
/* 1/10^x * 10^17 = 10^(17-x)=10^a
call fpow10i; /* st = 10^a
fld T*s; /* st = num,10^a
fmulp st1; /* st = num*10^a
fbstp T @bcd; /* st = vuoto; numero in memoria
/* ^^^^^^^^^^^^^^^^ salva numero in @bcd=[s+20] *come bcd*
/* ---------------- scrive nella stringa
a= & @bcd; b=@exp;
BcdToString( i, a, b, D[k+12], D[k+16] );
/* ---------------- ripristino
.ca: fld T*s; /* ricarica il numero nello fpu-stack
/* st = num
.cf: fldcw @wc_temp;
>> @string, @exp, @wc_temp, @bcd
s+=32
> b, c, r, i
s = k
> k;
ret 12
/* eax:len
/* BcdToString(char* string, char* bcd_number, uint exp, uint intN,
uint decN)
/* k == 0k, 4ra, 8@string, 12@bcd_number, 16@exp, 20IntN, 24decN
BcdToString:
< k ; k = s ;< b, c, r, i, j; s-=64
<< @string=[k+8], @bcd_number=[k+12], @exp=[k+16], @IntN=[k+20],
@DecN=[k+24]
j=s; i=@bcd_number; b=@exp; r=i; i+=8;
B*j='0'; ++j; /* serve per eventuale arrotondamento
al=*i; cl=*i; cl&=0xf; al>>=4; al+='0'; cl+='0';
al=='0'!#.c0
*j=cl; ++j; --i; #.c1
.c0: *j=al; ++b; [j+1]=cl; --i; j+=2;
.c1: al=*i; cl=*i; cl&=0xf; al>>=4; al+='0'; cl+='0';
*j=al; ++j; *j=cl; --i; ++j; i>=r#.c1;
B*j=0; /* ora in s[0..17]"0num" il numero di bcd
a=@IntN; a==0#.c2
##.c4
.c2: b<=17 !#.c3 /* b=exp=2<17 c=2, r=15
b==0 #.c3 /* c=1..17
r=@DecN; c=b; #.c5;
.c3: c=1; r=@DecN; #.c5;
/* b=exp, c=IntN, r=DecN
.c4: c=@IntN; r=@DecN;
.c5: c<17#.c6 | c=17;
.c6: a=17; a-=c; /* a=17-IntN
r<a #.c7 | r= a;
.c7: i=s; j=&[s+32];
b-=c; /* i=s b==exp
/* nota: c->1..17 r->17-c=0..16
/* arrotonda l'array in s nella cifra scelta
a=r; a+=c; a==17#.c8; /* nessun arrotondamento
round(j, i, a, 5); i=j;
/* posiziona il punto nell'array
.c8: j=@string;
.cm: B*i=='0'!#.cn /* puo' essere 0000num in un bcd?
++i; #.cm
.cn: B*i<'0'#.co; B*i>'9'#.co
#.c9
.co: D*j='0.0'; j+=3; #.cc
.c9: al=*i; *j=al; al==0#.cb; ++i,j; --c#.c9
B*i==0 #.cb;
r==0 #.cb; /* c=17: fine
B*j='.'; ++j;
.ca: al=*i; *j=al; al==0#.cb; ++i,j; --r#.ca
.cb: b==0#.cc
B*j='e'; ++j;
itoa(j, b); j+=a;
.cc: B*j=0;
a=@string; j-=a; a=j; ++a;
>> @string, @bcd_number, @exp, @IntN, @DecN
s+=64; > b, c, r, i, j; s = k ; > k;
ret 20
/* eax:len
/* round(char* array, char* origin, uint decimal[1..16], uint min)
/* k = 0k, 4ra, 8@array, 12@origin, 16@decimal, 20@min
round:
< k ; k = s ; < b, c, i, j
<< @array=[k+8], @origin=[k+12], @decimal=[k+16], @min=[k+20]
/*-----------------------------------
i=@origin; j=@array; b=@decimal; c=@min; ++b;
c>9#.ce; c<0#.ce; b<=1?#.ce; j==0#.ce; i==0#.ce; ##.c0
.ce: a=0; ##.cf;
.c0: cl+='0'; i+=b; j+=b;
*i>cl!#.c1
--b;
IncArray( D @array, D @origin, b); a=b; ++a; #.cf
.c1: *i<cl #.co
.c2: *i==cl!#.c3
++i; #.c2
.c3: B*i>'9'#.co; B*i<'0'#.co; *i<=cl#.co;
--b;
IncArray( D @array, D @origin, b); a=b; ++a; #.cf
.co: i=@origin; j=@array;
.c4: al=*i; *j=al;
++i; ++j; --b#.c4;
B*j=0;
a=@array; j-=a; a=j; ++a;
.cf:
>> @array, @origin, @decimal, @min
> b, c, i, j ; s = k ; > k;
ret 16
/* al:ah char IncNum<al>
IncNum:
al=='9'!#.c0
al='0'; ah=1; #.cf;
.c0: ++al; ah=0;
.cf:
ret
/* void IncArray(char* string, char* origin, uint pos)
/* string='0'+'number', pos in 'number'
/* 0j, 4i, 8c, 12a, 16ra, 20@string, 24@origin, 28@pos
/* incrementa la stringa di 1, string e' terminata in pos+1
IncArray:
< a, c, i, j
<< @string=[s+20], @origin=[s+24], @pos=[s+28]
/*-------------------------------------
a=@pos; j=@string; i=@origin; j+=a; i+=a; c=j; ah=1;
.c0: al=*i; al<'0'#.ce; al>'9'#.ce
ah==0#.c1 | IncNum();
.c1: *j=al; j==@string#.ce; --j; --i; #.c0;
.ce: ++c; B*c=0;
>> @string, @origin, @pos
> a, c, i, j
ret 12
ret
- Next message: Betov: "Re: my first .dll: why doesn't it work ..."
- Previous message: Ro : "Re: my first .dll: why doesn't it work ..."
- In reply to: Ro : "my first .dll: why doesn't it work ..."
- Next in thread: Betov: "Re: my first .dll: why doesn't it work ..."
- Reply: Betov: "Re: my first .dll: why doesn't it work ..."
- Reply: wolfgang kern: "Re: my first .dll: why doesn't it work ..."
- Reply: NoDot: "Re: my first .dll: why doesn't it work ..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|
|