From: randyhyde on
The recent exchange concerning the age-old bug in RosAsm has suggested
that the problems with RosAsm crashing are due to having a large
percentage of symbols in a program relative to the size of the source
file. Not that RosAsm should crash under these circumstances of course,
but I decided to be fair and try to "work around" this problem as Rene
expects his users to do.

So I wrote a short little HLA program that would generate a text file
that I could "cut & paste" into an existing RosAsm program (Base3.exe)
to test this theory out. Here's the HLA program that generates the
source code:

program main;
#include( "stdlib.hhf" )
begin main;

for( mov(0, ecx); ecx<10; inc( ecx )) do

stdout.put( "[a", ecx, ' ', (type uns32 ecx), "]", nl );
stdout.put( "mov al, B$a", ecx, nl );

endfor;


for( mov(10, ecx); ecx<1000; inc( ecx )) do

lea( edx, [ecx-10] );
lea( ebx, [ecx-5] );
lea( eax, [ecx-1] );
stdout.put
(
"[a",
ecx,
" (a", edx, "+",
"a", ebx, "+",
"a", eax, "+",
(type uns32 ecx),
")]",
nl
);
stdout.put( "mov al, a", ecx, nl );

endfor;



end main;


Each iteration of the loop generates two statements - an equate and a
mov instruction that loads AL (okay, really should have been EAX, but
we'll ignore that for now) with the value of that equate. Note that,
although the expressions are fairly complex, it's not like I'm
generating *really* long strings that a simple textual substitution
equate processor would choke on (due to buffer overflows). Here are
the first several lines taken from the file that this HLA program
produces:

[a0000_0000 0]
mov al, B$a0000_0000
[a0000_0001 1]
mov al, B$a0000_0001
[a0000_0002 2]
mov al, B$a0000_0002
[a0000_0003 3]
mov al, B$a0000_0003
[a0000_0004 4]
mov al, B$a0000_0004
[a0000_0005 5]
mov al, B$a0000_0005
[a0000_0006 6]
mov al, B$a0000_0006
[a0000_0007 7]
mov al, B$a0000_0007
[a0000_0008 8]
mov al, B$a0000_0008
[a0000_0009 9]
mov al, B$a0000_0009
[a0000_000A (a0000_0000+a0000_0005+a0000_0009+10)]
mov al, a0000_000A
[a0000_000B (a0000_0001+a0000_0006+a0000_000A+11)]
mov al, a0000_000B
[a0000_000C (a0000_0002+a0000_0007+a0000_000B+12)]
mov al, a0000_000C
[a0000_000D (a0000_0003+a0000_0008+a0000_000C+13)]
mov al, a0000_000D


Now if you cut & paste this (short) code sequence into the RosAsm
Base3.exe program, RosAsm will compile it just fine. So what happens
when we cut and paste the entire 2,000 lines? As I've come to expect,
RosAsm crashes and all data is lost (sorry, Ludwig, the "crash manager"
did not save the file before crashing; the data I pasted into Base3.exe
was lost).

Okay, RosAsm chokes on 1,000 statement pairs. It did work on about 13
statement pairs. Perhaps RosAsm can handle a fair number of these?
Nope. I put in 20 pairs of these statements, that is:

[a0000_0000 0]
mov al, B$a0000_0000
[a0000_0001 1]
mov al, B$a0000_0001
[a0000_0002 2]
mov al, B$a0000_0002
[a0000_0003 3]
mov al, B$a0000_0003
[a0000_0004 4]
mov al, B$a0000_0004
[a0000_0005 5]
mov al, B$a0000_0005
[a0000_0006 6]
mov al, B$a0000_0006
[a0000_0007 7]
mov al, B$a0000_0007
[a0000_0008 8]
mov al, B$a0000_0008
[a0000_0009 9]
mov al, B$a0000_0009
[a0000_000A (a0000_0000+a0000_0005+a0000_0009+10)]
mov al, a0000_000A
[a0000_000B (a0000_0001+a0000_0006+a0000_000A+11)]
mov al, a0000_000B
[a0000_000C (a0000_0002+a0000_0007+a0000_000B+12)]
mov al, a0000_000C
[a0000_000D (a0000_0003+a0000_0008+a0000_000C+13)]
mov al, a0000_000D
[a0000_000E (a0000_0004+a0000_0009+a0000_000D+14)]
mov al, a0000_000E
[a0000_000F (a0000_0005+a0000_000A+a0000_000E+15)]
mov al, a0000_000F
[a0000_0010 (a0000_0006+a0000_000B+a0000_000F+16)]
mov al, a0000_0010
[a0000_0011 (a0000_0007+a0000_000C+a0000_0010+17)]
mov al, a0000_0011
[a0000_0012 (a0000_0008+a0000_000D+a0000_0011+18)]
mov al, a0000_0012
[a0000_0013 (a0000_0009+a0000_000E+a0000_0012+19)]
mov al, a0000_0013
[a0000_0014 (a0000_000A+a0000_000F+a0000_0013+20)]
mov al, a0000_0014

And RosAsm crashes, losing all data in memory.

Bzzzzzzt. Game over.

Sorry Ludwig, sorry Rene. There is a *serious* problem here. You can't
blame it on not allocating a sufficient amount of memory. You can't
claim that it's okay because the crash manager preserves the file
should a crash actually occur. You can't claim that no one would ever
create a program with *so many* equates (we're talking *20* equates
here).

If such a trivially simple program crashes RosAsm, how can anyone trust
this program? And mind you, it's not like I set out to find the
smallest program that would crash RosAsm. This is the first thing I
tried. Attempting to avoid the programs I wrote in the past that
crashed RosAsm, I tried a completely different approach this time. I
was more interested in measuring RosAsm's speed than trying to crash
it; once again I've found that messing with RosAsm is simply a waste of
time.

BTW, it goes without saying that I downloaded the latest version of
RosAsm prior to running this test.
Cheers,
Randy Hyde

P.S. For the record, here's the Base3.exe source file, showing where I
cut & paste the code. As you can clearly see, the issue of source file
size compared to number of equates is a non-issue here:

___________________________________________________________________________________________
___________________________________________________________________________________________

; Base3.exe Example with Standard Menu and set of
Macros.
;
; Hll Style version.
;
; This HLL version is the one I will continue to use in my Tuts and
Demos. It is somewhat less
; HLL like than Base4.exe and closer to the RosAsm basic rules. I.E.
Beginner friendly.
;
; // 'api' Macros of Base2.exe are stripped off: a Tasm like 'Call'
instead (works the same).
; // The default 'D' for local Labels is required to conform with the
basic syntax.
; // The 'Proc' Macros do not include the control for transmitted
parameters number.
___________________________________________________________________________________________
___________________________________________________________________________________________
; Some basic Macros:

[push | push #1 | #+1] [pop | pop #1 | #+1]

[mov | mov #1 #2 | #+2]
[inc | inc #1 | #+1] [dec | dec #1 | #+1]

[On | cmp #1 #3 | jn#2 o1> | #4>L | o1:]

[call | push #L>2 | call #1]

[move | push #2 | pop #1 | #+2]

[If | cmp #1 #3 | jn#2 I0>]
[.If | cmp #1 #3 | jn#2 I1>>]
[..If | cmp #1 #3 | jn#2 I2>>]
[...If | cmp #1 #3 | jn#2 I3>>]

[Else_if | jmp I5> | I0: | cmp #1 #3 | jn#2 I0>]
[.Else_if | jmp I6>> | I1: | cmp #1 #3 | jn#2 I1>>]
[..Else_if | jmp I7>> | I2: | cmp #1 #3 | jn#2 I2>>]
[...Else_if | jmp I8>> | I3: | cmp #1 #3 | jn#2 I3>>]

[Else | Jmp I5> | I0:]
[.Else | Jmp I6>> | I1:]
[..Else | Jmp I7>> | I2:]
[...Else | Jmp I8>> | I3:]

[End_if | I0: | I5:]
[.End_if | I1: | I6:]
[..End_if | I2: | I7:]
[...End_if | I3: | I8:]


; If_Or eax = 1, eax = 5, eax =122

[If_Or | cmp #1 #3 | j#2 O0> | #+3 | jmp I0> | O0:]
[.If_Or | cmp #1 #3 | j#2 O1> | #+3 | jmp I1> | O1:]
[..If_Or | cmp #1 #3 | j#2 O2> | #+3 | jmp I2> | O2:]
[...If_Or | cmp #1 #3 | j#2 O3> | #+3 | jmp I3> | O3:]

; If_And eax = 1, ebx = 5, ecx =122

[If_And | cmp #1 #3 | jn#2 I0> | #3]
[.If_And | cmp #1 #3 | jn#2 I1> | #3]
[..If_And | cmp #1 #3 | jn#2 I2> | #3]
[...If_And | cmp #1 #3 | jn#2 I3> | #3]



[While | W0: | cmp #1 #3 | jn#2 W9>]
[End_While | jmp W0< | W9:]

[.While | X0: | cmp #1 #3 | jn#2 X9>>]
[.End_While | jmp X0<< | X9:]

[Do | D0:]
[Loop_Until | cmp #1 #3 | jn#2 D0<]
[Do_Loop | Loop D0<]

[.Do | E0:]
[.Loop_Until | cmp #1 #3 | jn#2 E0<<] ; long
[.Do_Loop | Loop E0<]

_________________________________________________________________________________________
; Added Equates for a more HLL like style in comparison to Macros:

[= e < b > a =< be <= be => ae >= ae <> ne]
_________________________________________________________________________________________
_________________________________________________________________________________________
; Proc Macros and Equates. Internal storages are:
;
; &1 <<< Size of Argument(s) (for ending Ret n, in EndP). Set by
Argument(s)
; &2 <<< Size of Local (for Stack Management). Set by Local
; &3 <<< What to pop before ret. Set by User.

[Proc | &1=0 | &2=0 | &3= | #1 | push ebp | mov ebp esp]

[Exit | jmp P9>>]

[Arguments | {#1 Arg#x} | #+1 | &1=SizeOf#x]
[Argument | {#1 Arg#x} | #+1 | &1=SizeOf#x]

[Local | {#1 Local#x} | #+1 | sub esp SizeOf#x | &2=SizeOf#x]

[StrucPtrs | {#3 ebp+#2+#F} | #+2]

[Structure | {#1 ebp-&2-4} | sub esp #2+4 | mov D$#1 esp | StrucPtrs
0-&2-#2-4 #L>3]

[Uses | push #1>L | &3=pop #L>1]

[EndP | P9: | &3 | mov esp ebp | pop ebp | ret &1]

; For pointing to transmitted parameters (upper "Arg#x" fall here):

[Arg1 ebp+8 Arg2 ebp+12 Arg3 ebp+16 Arg4 ebp+20 Arg5 ebp+24
Arg6 ebp+28 Arg7 ebp+32 Arg8 ebp+36 Arg9 ebp+40 Arg10
ebp+44]

; For pointing Local Stack declared data (upper "Local#x" fall here):

[Local1 ebp-4 Local2 ebp-8 Local3 ebp-12 Local4 ebp-16
Local5 ebp-20
Local6 ebp-24 Local7 ebp-28 Local8 ebp-32 Local9 ebp-36
Local10 ebp-40]

; To help preventing from stack sizes' mistakes (upper "SizeOf#x" fall
here):

[SizeOf1 4 SizeOf2 8 SizeOf3 12 SizeOf4 16 SizeOf5 20
SizeOf6 24 SizeOf7 28 SizeOf8 32 SizeOf9 36 SizeOf10 40]


_________________________________________________________________
[Argh: 'Aaarrrghhh!!!!....', 0 Whaoo: 'Whaaaaoooo!!!!....', 0]

[MessageBox | {&0: #2 0} | call 'USER32.MessageBoxA' &NULL &0 #1
&MB_SYSTEMMODAL__&MB_OK]

; ... to be called, for example, by:
;
; > MessageBox Whaoo 'Oh! No, please!!! not that again!...'

___________________________________________________________________________________________
; Data:

[FirstMessage: 0 #7] ; For
"GetMessage"

[WindowClass: ;
Window Class Structure
style: 3 lpfnWndProc: MainWindowProc cbClsExtra: 0 cbWndExtra: 0
hInstance: 0 hIcon: 0 hCursor: 0 hbrBackground: 6
lpszMenuName: 0 lpszClassName: WindowClassName]

[WindowHandle: 0 MenuHandle: 0]

[WindowClassName: B$ 'Anything' 0 WindowCaption: 'Base App' 0]

[WindowX: 50 WindowY: 50 WindowW: 650 WindowH: 450]

___________________________________________________________________________________________
Main:
call 'Kernel32.GetModuleHandleA' 0 | mov D$hInstance eax

call 'User32.LoadIconA' D$hInstance 1 | mov D$hIcon eax

call 'User32.LoadCursorA' 0 &IDC_ARROW | mov D$hCursor eax

call 'User32.RegisterClassA' WindowClass

call 'User32.LoadMenuA' D$hInstance M00_Menu | mov D$MenuHandle eax

call 'User32.CreateWindowExA' &WS_EX_CLIENTEDGE WindowClassName
WindowCaption,
&WS_OVERLAPPEDWINDOW__&WS_VISIBLE,
D$WindowX D$WindowY D$WindowW
D$WindowH 0,
D$MenuHandle D$hInstance 0
mov D$WindowHandle eax

call 'User32.ShowWindow' D$WindowHandle &SW_SHOW
call 'User32.UpdateWindow' D$WindowHandle


jmp L1>

While eax <> 0
call 'User32.TranslateMessage' FirstMessage
call 'User32.DispatchMessageA' FirstMessage
L1: call 'USER32.GetMessageA' FirstMessage 0 0 0
End_While

call 'Kernel32.ExitProcess' &NULL

___________________________________________________________________________________________
; These menu equates are given by the menu editor ([ClipBoard]):

[M00_Menu 2000 M00_New 2001
M00_Open 2002
M00_Save 2003 M00_Save_As 2004
M00_Exit 2005
M00_Undo 2006 M00_Cut 2007
M00_Copy 2008
M00_Paste 2009 M00_Delete 2010
M00_Select_All 2011
M00_About 2012]
___________________________________________________________________________________________
Proc MainWindowProc:
Arguments @Adressee @Message @wParam @lParam

pushad

.If D(a)Message = &WM_CLOSE
call 'USER32.DestroyWindow' D(a)Adressee

.Else_If D(a)Message = &WM_DESTROY
call 'User32.PostQuitMessage' 0

.Else_If D(a)Message = &WM_COMMAND
If D(a)wParam = M00_Exit
call 'User32.SendMessageA' D(a)Adressee &WM_CLOSE 0 0

; Else_If D(a)wParam = M00_...
; ...

; Else_If D(a)wParam = M00_About
; ...

Else
MessageBox InfoTitle "
This file is not a Demo. It is a 'StartUp'
Base You can use to develop your own work. "

End_If
.Else
popad
call 'User32.DefWindowProcA' D(a)Adressee D(a)Message D(a)wParam
D(a)lParam
Exit

.End_If

popad | mov eax &FALSE




[a0000_0000 0]
mov al, B$a0000_0000
[a0000_0001 1]
mov al, B$a0000_0001
[a0000_0002 2]
mov al, B$a0000_0002
[a0000_0003 3]
mov al, B$a0000_0003
[a0000_0004 4]
mov al, B$a0000_0004
[a0000_0005 5]
mov al, B$a0000_0005
[a0000_0006 6]
mov al, B$a0000_0006
[a0000_0007 7]
mov al, B$a0000_0007
[a0000_0008 8]
mov al, B$a0000_0008
[a0000_0009 9]
mov al, B$a0000_0009
[a0000_000A (a0000_0000+a0000_0005+a0000_0009+10)]
mov al, a0000_000A
[a0000_000B (a0000_0001+a0000_0006+a0000_000A+11)]
mov al, a0000_000B
[a0000_000C (a0000_0002+a0000_0007+a0000_000B+12)]
mov al, a0000_000C
[a0000_000D (a0000_0003+a0000_0008+a0000_000C+13)]
mov al, a0000_000D




EndP



______________________________________________________________________________________
; little message routines for values tests (dWords only / text pointer)
to be called with:
; > Hexprint D$esi / showme esi+5, for example:

[InfoTitle: 'Application Base', 0]

[HexprintString: B$ ' h' 0
MessageTitle: 'HihoHiho' 0]


Proc HexPrnt:
Arguments @N

pushad
mov ebx D@N, ecx 8, edi HexPrintString | add edi 7
std
Do
mov al bl | and al 0F | add al '0'
On al > '9', add al 7
stosb | shr ebx 4
Do_Loop
cld
call 'USER32.MessageBoxA' 0 HexPrintString MessageTitle
&MB_OK__&MB_SYSTEMMODAL
popad
EndP

[Hexprint | call Hexprnt #1 | #+1]


Proc ShowYou:
Arguments @Pointer

pushad
call 'USER32.MessageBoxA' &NULL D(a)Pointer MessageTitle
&MB_SYSTEMMODAL__&MB_OK
popad
EndP

[Showme | push eax | lea eax D$#1 | call ShowYou eax | pop eax]

_______________________________________________________________________________________

From: Betov on
randyhyde(a)earthlink.net ýcrivait
news:1117768517.847816.306860(a)o13g2000cwo.googlegroups.com:

:)))))

I already told you that this "problem" :)) will be kept
preciously alive, forever, in order to make it impossible
for you to do what you want to do.

For the RosAsm users who would want to do such a stupid
thing (they are allowed to do stupid things, if they like
to...), i tell them how to do it, under the expressed
condition that they promiss to not make it public.

:)

Betov.

< http://rosasm.org >



From: hutch-- on
Come on Betov, the only leg you are pulling here is your own (I won't
say which one as it may make Annie blush). RosAsm falls over with
anything above trivial data and you just don't know how to fix it.

Maybe you should tie a knot in IT instead and start learning something
about data structures.

Muhahahaha

hutch at movsd dot com

From: Frank Kotler on
Betov wrote:

> For the RosAsm users who would want to do such a stupid
> thing (they are allowed to do stupid things, if they like
> to...), i tell them how to do it, under the expressed
> condition that they promiss to not make it public.
>
> :)

Jeez! I hope the anti-GPL forces don't learn of this
technique!

Best,
Frank
From: justonce on
Hi,
I'm very new to assembly so I tried to understand the first message in
that thread.
I didn't understand it.

I downloaded Rosasm, pasted the code : it compiled, run in the debuger and
as expected, when I closed the window, the debuger showed the message :
ACCESS VIOLATION [C0000005]
The thread tried to read from or write to a virtual address for which it
does not have the appropriate access.
Instruction that raised the exception :
mov al B$0

Normal, Windows doesn't allow access at ram address 0.

In fact, you don't need 1000 or even 13 instructions. Only one is enough :

[a0000_0000 0]
mov al, B$a0000_0000

or simpler :
mov al B$0


I tried then with Hide.
I don't know all the strange syntax for this assembler, so I changed the
code

mov ebx 0
mov al B$ebx

So in Hide :
// hello world console demo
// for more projects and sources,
// download the HIDE Projects package

program hw_console;

#includeonce("stdlib.hhf")

begin hw_console;

stdout.put("Hello world of assembly",nl);
mov( 0, ebx );
mov([ebx], eax);
end hw_console;

And of course, the compiled program raises an exception.


So, I don't understand : what is Mr Hyde talking about ??
Please help me to understand.

Regards.

 |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10
Prev: MultiWindowed Adventure Game
Next: Assembler for Dummies