This is an actual assembly question. :-)
Wine under Linux claims to run 100s of programs.
It can not run this fireworks program. (and every program that I have written and/or modified.)
I filed a bug report with Wine.
They asked for the source code and the exe.
And this was their last response.
(And boy are they a bit anal retentive.)
QuotePlease don't paste such long source, attach it instead.
While firework2.exe downloaded from the above mentioned site work under
Windows XP it crashes under Windows 7 almost same way as under Wine.
Looks like a stack corruption caused by hand written floating point/MMX code.
Can someone test it under Win 7 please ?
What the heck is "hand written floating point/MMX code" ??
I thought all FPU code was hand written.
Appreciate the help.
Works fine on XP but with Win7-64 it chokes in line 354 with access violation:
fld dword ptr[edi+ecx+4]
Thanks, I will research what that means.
Fpu code is pretty foreign to me.
My brain can only hold so much info.
Second semester Organic Chemistry was a D for me.
The book was twice the size of a bible. :-)
Some other responses.
Quote1. There are pushes without corresponding pops or stack adjustments
2. what calling convention is used, are there registers that should be
preserved?
3. giving that code also uses threads , there are also other
possibilities for crash
4. wine is less prohibitive than Windows regarding not preserving
registers
Looks like I have to relearn assembly.
No problem, I know I need too. :-)
Does this push have the appropriate pop ?
Quotepush eax
fild dword ptr[esp]
fsqrt
fidiv lum ; this code is -nonlinear-
fld1
fsubrp st(1),st(0)
fmul st(0),st(0) ; curve
fmul st(0),st(0) ; curve more
fimul tff
fistp dword ptr[esp]
pop ebx
******* You don't seem to know what is the preservation rule.
Add "uses esi edi ebx" to your proc using those register.
********use local variables instead of [esp + N] ,you can just made errors with this form of adressing.
The form [esp + n] can be use only when the prog is working and you want to win a few ยต seconds.
****** use a debugger
I have not written any assembly in over a year.
I will look up uses and the preservation rule.
According to here
https://msdn.microsoft.com/en-us/library/k1a8ss06.aspx
QuoteWhen using __asm to write assembly language in C/C++ functions, you don't need to preserve the EAX, EBX, ECX, EDX, ESI, or EDI registers.
Since I do not have Win 7, I can not test if my modifications will work with Win 7.
So, did Win 7 become more strict in what works as opposed to XP ?
except if have made a real mistake , the code i have downloaded is in masm language not in c.
You need to preserve the registers.
When you made an escape from c with the _asm directive,the c compiler take care of that for you.
It's not the case for a masm compiler.
Rewrite your code with the preserve rule and local variable,I will test it on Windows 10.
MonPROC PROC uses esi edi ebx MyArg:DWORD
Local othervariable[4]:BYTE ;or Local othervariable:DWORD
ret
MonPROC endp
Thanks.
I looked thru the code examples and could not find an example of
uses esi edi ebx
I need an example to study.
C:\MASM32\SOURCE\fire.asm(603) : error A2137: too few arguments to INVOKE
Light_Flash3 PROC uses ebx esi edi x1:DWORD, y1:DWORD, lum:DWORD, src:DWORD, des:DWORD,
my:DWORD, x2:DWORD, y2:DWORD, tff:DWORD
LOCAL mx:DWORD
mov eax,lum
shr eax,1 ; Light_Flash: dynamic 2D lighting routine
mov lum,eax ; does not uses any pre-computed data
mov tff,255 ; ie. pure light frum tha melting cpu core :)
mov eax,maxx
mov mx,eax
mov eax,maxy
dec eax
mov my,eax
mov esi,src
mov edi,des
xor eax,eax
mov y2,eax
ylp3: ; 2x2 instead of per pixel lighting
xor eax,eax ; half the quality, but higher speed
mov x2,eax
xlp3:
mov eax,y2
sub eax,y1
imul eax
mov ebx,x2
sub ebx,x1
imul ebx,ebx
add eax,ebx
mov edx,lum
imul edx,edx
xor ebx,ebx
cmp eax,edx
ja @F ; jump to end causes time waves
push eax
fild dword ptr[esp]
fsqrt
fidiv lum ; this code is -nonlinear-
fld1
fsubrp st(1),st(0)
fmul st(0),st(0) ; curve
fmul st(0),st(0) ; curve more
fimul tff
fistp dword ptr[esp]
pop ebx
imul ebx,01010101h
@@:
mov eax,y2
imul maxx
add eax,x2
lea eax,[eax+eax*2]
mov edx,maxx
lea edx,[edx+edx*2]
add edx,eax
movd MM2,ebx ; simply add with saturation
movq MM0,[esi+eax] ; gamma correction is against this code
psllq MM2,32
movq MM1,[esi+edx]
movd MM3,ebx
por MM2,MM3
paddusb MM0,MM2
movd [edi+eax],MM0
paddusb MM1,MM2
psrlq MM0,32
movd [edi+edx],MM1
movd ebx,MM0
psrlq MM1,32
mov [edi+eax+4],bx
movd ecx,MM1
mov [edi+edx+4],cx
emms
@@:
mov eax,x2
add eax,2
mov x2,eax
cmp eax,mx
jbe xlp3
mov eax,y2
add eax,2
mov y2,eax
cmp eax,my
jbe ylp3
ret
Light_Flash3 ENDP
C:\MASM32\SOURCE\fire.asm(603) : error A2137: too few arguments to INVOKE
Flash PROTO x:DWORD,y:DWORD,z:DWORD
invoke Flash,1,2 ;error A2137: too few arguments to INVOKE
invoke Flash,1,2,3 ;correct
There is not only Light_Flash3 who use esi edi ebx.
Use the first post,and put your new asm (the zip can be replaced)
other soluce
.code
Flash PROC x:DWORD,y:DWORD,z:DWORD
ret
Flash ENDP
start:
invoke Flash,1,2,3 ;work without proto because the proc is placed before
end start
I was told this is the problem.
Can someone help me understand and fix it ?
Quote--- snip ---
FireThread:
[...]
sub ebp,12 ; as 3 local variables
--- snip ---
The register %ebp was never properly initialized, effectively corrupting the variables of the parent function.
Depending on the Windows version, the registers are initialized a bit different, effectively hiding all the trouble on Windows XP.
Firethread PROC uses esi edi ebx
Local JKg:DWORD,JKL:DWORD,HJL:DWORD
invoke exitthread ;written as i can
ret
Firethread ENDP
To not close the main prog:
invoke CloseHandle,Htread
The thread is not close immediatly,need time
invoke WaitForSingleObject,Htread,INFINITE
I do not understand what you want me to do.
I made some changes.
WndProc PROC hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
Quotepush esi
push edi
push ebx
And I popped those register before the return.
Could you test it in Win 7 ?
Going back to an earlier post.
Quote--- snip ---
FireThread:
[...]
sub ebp,12 ; as 3 local variables
--- snip ---
The register %ebp was never properly initialized, effectively corrupting the variables of the parent function.
Was ebp not properly initialized ?
If it wasn't, how do I fix it ?
If I try enuf things, eventually something will work. :-)
Quote from: Magnum on February 29, 2016, 12:20:32 PM
Was ebp not properly initialized ?
If it wasn't, how do I fix it ?
we don't know - you can't show one line of code and expect us to gleen the context
but, i am guessing....
sub ebp,12
generally, we load EBP with the contents of ESP at some point
this creates a "stack frame"
i.e., while ESP goes up and down due to PUSHes and POPs, EBP remains stable, providing a fixed reference point
after the stack frame base pointer has been initialized, we modify ESP to create stack space for locals, not EBP
push ebp
mov ebp,esp ;EBP = stack frame base pointer
sub esp,12 ;create stack space for 3 dword local variables
; body of routine code here
mov esp,ebp
pop ebp
ret
Attached is source code.
It works in XP, but not in Win 7.
I need it to work in Win 7 and then it should work under Wine.
Dave,
You get 100 gold stars.
;sub ebp,12 ; as 3 local variables
sub esp,12
I learned that the original code did create the stack space for 3 dword local variables correctly.
This correction should allow it to work in Win 7.
Would appreciate someone testing this on Win 7.
it work in win10
can you post your final source code ?
Sure can. :-)
There is a problem with allocated memory,you add Something to the original pointer and it is this one
who must be used for free
FireThread:
invoke SetThreadPriority,idThread1,THREAD_PRIORITY_NORMAL;HIGHEST
invoke GetDC,hwnd
mov wnddc,eax
invoke GetProcessHeap
mov hHeap,eax
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,4194304
mov Heapbitmap1,eax ;<<<<<<<<<<<<<<<<<< keep this one for free
add eax,4096 ; blur: -1'th line problem
mov bitmap1,eax
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,4194304
mov Heapbitmap2,eax ;<<<<<<<<<<<<<<<<<< keep this one for free
add eax,4096 ; blur: -1'th line problem
mov bitmap2,eax
mov eax,nd
shl eax,4
add eax,SPARC
mov sb,eax ; size of FShell = nd*16+8
imul nb ; array size = nb*sb
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,eax
mov hFShells,eax
finit ; initialise floating point unit
mov ax,07fh ; low precision floats
mov word ptr[esp-4],ax ; fireworks... not space rockets
fldcw word ptr[esp-4]
; PROBLEM HERE ?? ebp was never properly initialized
;sub ebp,12 ; as 3 local variables
sub esp,12 ; CORRECT statment
mov eax,nb
mov [ebp],eax
mov eax,hFShells
mov [ebp+4],eax
initshells:
lp1:
mov eax,motionQ
mov dword ptr[ebp+8],eax
lp2:
mov eax,nb
mov [ebp],eax
mov eax,hFShells
mov [ebp+4],eax
lp3:
invoke FShell_render,[ebp+4],[ebp]
mov eax,GMode
mov ecx,offset FShell_explodeAG
mov ebx,offset FShell_explodeOS
test eax,eax
cmovz ecx,ebx
push [ebp+4] ;
call ecx
test eax,eax
jns @F
invoke random,maxy
push eax
mov eax,maxx
add eax,eax
invoke random,eax
mov edx,maxx
shr edx,1
sub eax,edx
push eax
push [ebp+4]
call FShell_recycle
@@:
mov eax,sb
add [ebp+4],eax
dec dword ptr[ebp]
jnz lp3
dec dword ptr[ebp+8]
jnz lp2
mov eax,EMode
test eax,eax
jz r1
mov eax,CMode ; switch pre/post blur according to -
test eax,eax ; current chemical in fire
jz @F
invoke Blur_MMX2
@@:
invoke Light_Flash3,lightx,lighty,flash,bitmap1,bitmap2
invoke SetDIBitsToDevice,wnddc,0,0,maxx,maxy,\
0,0,0,maxy,bitmap2,ADDR bminf,DIB_RGB_COLORS
mov eax,CMode
test eax,eax
jnz r2
invoke Blur_MMX2
jmp r2
r1:
invoke SetDIBitsToDevice,wnddc,0,0,maxx,maxy,\
0,0,0,maxy,bitmap1,ADDR bminf,DIB_RGB_COLORS
mov eax,maxx
imul maxy
lea eax,[eax+eax*2]
invoke RtlZeroMemory,bitmap1,eax
r2:
inc fcount ; count the frames
fild flash
fmul flfactor
fistp flash
invoke Sleep,5 ; control, if frames rate goes too high
mov eax,stop
test eax,eax
jz lp1
invoke ReleaseDC,hwnd,wnddc
invoke HeapFree,hHeap,0,Heapbitmap1; <<<<<<<<<< free the good one
mov eax,Heapbitmap1
.if eax != Heapbitmap2
invoke HeapFree,hHeap,0,Heapbitmap2 ; <<<<<<<<<< free the good one
.endif
invoke HeapFree,hHeap,0,hFShells
mov idThread1,-1
invoke ExitThread,2003
hlt ; ...! i8085 memories
There is also problems with preservation
windbg see Nothing in the corrected source (Windows 10)
Quote from: ToutEnMasm on March 01, 2016, 05:27:19 AM
There is a problem with allocated memory,you add Something to the original pointer and it is this one
who must be used for free
FireThread:
invoke SetThreadPriority,idThread1,THREAD_PRIORITY_NORMAL;HIGHEST
invoke GetDC,hwnd
mov wnddc,eax
invoke GetProcessHeap
mov hHeap,eax
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,4194304
mov Heapbitmap1,eax ;<<<<<<<<<<<<<<<<<< keep this one for free
add eax,4096 ; blur: -1'th line problem
mov bitmap1,eax
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,4194304
mov Heapbitmap2,eax ;<<<<<<<<<<<<<<<<<< keep this one for free
add eax,4096 ; blur: -1'th line problem
mov bitmap2,eax
mov eax,nd
shl eax,4
add eax,SPARC
mov sb,eax ; size of FShell = nd*16+8
imul nb ; array size = nb*sb
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,eax
mov hFShells,eax
finit ; initialise floating point unit
mov ax,07fh ; low precision floats
mov word ptr[esp-4],ax ; fireworks... not space rockets
fldcw word ptr[esp-4]
; PROBLEM HERE ?? ebp was never properly initialized
;sub ebp,12 ; as 3 local variables
sub esp,12 ; CORRECT statment
mov eax,nb
mov [ebp],eax
mov eax,hFShells
mov [ebp+4],eax
initshells:
lp1:
mov eax,motionQ
mov dword ptr[ebp+8],eax
lp2:
mov eax,nb
mov [ebp],eax
mov eax,hFShells
mov [ebp+4],eax
lp3:
invoke FShell_render,[ebp+4],[ebp]
mov eax,GMode
mov ecx,offset FShell_explodeAG
mov ebx,offset FShell_explodeOS
test eax,eax
cmovz ecx,ebx
push [ebp+4] ;
call ecx
test eax,eax
jns @F
invoke random,maxy
push eax
mov eax,maxx
add eax,eax
invoke random,eax
mov edx,maxx
shr edx,1
sub eax,edx
push eax
push [ebp+4]
call FShell_recycle
@@:
mov eax,sb
add [ebp+4],eax
dec dword ptr[ebp]
jnz lp3
dec dword ptr[ebp+8]
jnz lp2
mov eax,EMode
test eax,eax
jz r1
mov eax,CMode ; switch pre/post blur according to -
test eax,eax ; current chemical in fire
jz @F
invoke Blur_MMX2
@@:
invoke Light_Flash3,lightx,lighty,flash,bitmap1,bitmap2
invoke SetDIBitsToDevice,wnddc,0,0,maxx,maxy,\
0,0,0,maxy,bitmap2,ADDR bminf,DIB_RGB_COLORS
mov eax,CMode
test eax,eax
jnz r2
invoke Blur_MMX2
jmp r2
r1:
invoke SetDIBitsToDevice,wnddc,0,0,maxx,maxy,\
0,0,0,maxy,bitmap1,ADDR bminf,DIB_RGB_COLORS
mov eax,maxx
imul maxy
lea eax,[eax+eax*2]
invoke RtlZeroMemory,bitmap1,eax
r2:
inc fcount ; count the frames
fild flash
fmul flfactor
fistp flash
invoke Sleep,5 ; control, if frames rate goes too high
mov eax,stop
test eax,eax
jz lp1
invoke ReleaseDC,hwnd,wnddc
invoke HeapFree,hHeap,0,Heapbitmap1; <<<<<<<<<< free the good one
mov eax,Heapbitmap1
.if eax != Heapbitmap2
invoke HeapFree,hHeap,0,Heapbitmap2 ; <<<<<<<<<< free the good one
.endif
invoke HeapFree,hHeap,0,hFShells
mov idThread1,-1
invoke ExitThread,2003
hlt ; ...! i8085 memories
There is also problems with preservation
windbg see Nothing in the corrected source (Windows 10)
Look at 1st line of code to see the change.
?????? Look at 1st line of code to see the change ??????
don't understang
The modifies must be made to avoid a crash when closing the prog (wrong pointer)
I made all your recommended changes.
New source attached.
You said it worked in Win 10.
I guess you found some more errors.
I lost my copy of the executable.
Would someone mind compiling it for me.
Thanks,
Andy
from 2016
Thanks HSE. I am running Ubuntu-Mate from having migrated from Win XP.
When I run fire.exe, it opens in a small window and it runs ok.
When I increase the window size, it crashes.
It uses about 25% of my cpu when running.
I wonder if changing thread priority would help?
FireThread:
invoke SetThreadPriority,idThread1,THREAD_PRIORITY_NORMAL;HIGHEST
invoke GetDC,hwnd
Unhandled exception: page fault on read access to 0x00e26ef8 in 32-bit code (0x004010d2).
Register dump:
CS:0023 SS:002b DS:002b ES:002b FS:006b GS:0063
EIP:004010d2 ESP:0061fea4 EBP:0061feb8 EFLAGS:00010206( R- -- I - -P- )
EAX:003ffc30 EBX:00000000 ECX:00000000 EDX:00400ed8
ESI:00a26020 EDI:00625020
Stack dump:
0x0061fea4: 000000ff 0000036e 00000000 00000370
0x0061feb4: 00000638 0061feec 004015d3 00000428
0x0061fec4: 0000027f 0000000a 00a26020 00625020
0x0061fed4: 00110000 00000008 0000007f 7bc7da10
0x0061fee4: 00010001 00010001 00000000 0015d570
0x0061fef4: 00000000 00000000 7bcdbcb4 7bcdbcb4
Backtrace:
=>0 0x004010d2 in fire (+0x10d2) (0x0061feb8)
1 0x004015d3 in fire (+0x15d2) (0x0061feec)
0x004010d2: movq 0x0(%edx,%esi,1),%mm1
Modules:
Module Address Debug info Name (9 modules)
PE 400000- 404000 Export fire
PE 7b410000-7b5b6000 Deferred kernel32
PE 7bc10000-7bc14000 Deferred ntdll
PE 7f460000-7f464000 Deferred winex11
PE 7f4f0000-7f4f4000 Deferred imm32
PE 7f8e0000-7f9a6000 Deferred user32
PE 7fac0000-7fac4000 Deferred advapi32
PE 7fb40000-7fb47000 Deferred gdi32
PE 7ffd0000-7ffd4000 Deferred version
Threads:
process tid prio (all id:s are in hex)
0000000e services.exe
00000030 0
0000002d 0
00000028 0
0000001f 0
00000015 0
00000010 0
0000000f 0
00000011 mscorsvw.exe
0000001a 0
00000019 0
00000018 0
00000012 0
0000001b winedevice.exe
00000024 0
00000021 0
00000020 0
0000001c 0
0000001d winedbg.exe
0000001e 0
00000025 plugplay.exe
0000002a 0
00000029 0
00000026 0
0000002b winedevice.exe
00000035 0
0000002f 0
0000002e 0
0000002c 0
Was a console building. New build.
Unhandled exception: page fault on write access to 0x00e6538e in 32-bit code (0x00401349).
Register dump:
CS:0023 SS:002b DS:002b ES:002b FS:006b GS:0063
EIP:00401349 ESP:0061feb0 EBP:0061fec4 EFLAGS:00010202( R- -- I - - - )
EAX:0043f36e EBX:00000592 ECX:000018f0 EDX:00aad580
ESI:00a26020 EDI:00155830
Stack dump:
0x0061feb0: 00aad580 0000077c 000003c2 00000097
0x0061fec0: 0000016e 0061feec 0040153a 00155820
0x0061fed0: 00000005 00110000 00000008 0000007f
0x0061fee0: 7bc7da10 00010001 00010001 00000005
0x0061fef0: 00155820 00000010 00000000 7bcdbcb4
0x0061ff00: 7bcdbcb4 00000000 00000000 0040146c
Backtrace:
=>0 0x00401349 in fire (+0x1349) (0x0061fec4)
1 0x0040153a in fire (+0x1539) (0x0061feec)
0x00401349: movw %dx,0x0(%eax,%esi,1)
Modules:
Module Address Debug info Name (9 modules)
PE 400000- 404000 Export fire
PE 7b410000-7b5b6000 Deferred kernel32
PE 7bc10000-7bc14000 Deferred ntdll
PE 7f460000-7f464000 Deferred winex11
PE 7f4f0000-7f4f4000 Deferred imm32
PE 7f8e0000-7f9a6000 Deferred user32
PE 7fac0000-7fac4000 Deferred advapi32
PE 7fb40000-7fb47000 Deferred gdi32
PE 7ffd0000-7ffd4000 Deferred version
Threads:
process tid prio (all id:s are in hex)
0000000e services.exe
00000030 0
0000002d 0
00000028 0
0000001f 0
00000015 0
00000010 0
0000000f 0
00000011 mscorsvw.exe
0000001a 0
00000019 0
00000018 0
00000012 0
0000001b winedevice.exe
00000024 0
00000021 0
00000020 0
0000001c 0
0000001d winedbg.exe
0000001e 0
00000025 plugplay.exe
0000002a 0
00000029 0
00000026 0
0000002b winedevice.exe
00000035 0
0000002f 0
0000002e 0
0000002c 0
ABI corrections in previous post.
What is ABI?
Andy,
In 32 bit its the Intel "Application Binary Interface" which specifies register preservation rules.
Thanks. I will see if Ollydbg will run in Linux.
And study the output.
Quote from: Magnum on August 29, 2018, 04:27:39 AM
What is ABI?
Search forum :biggrin:
The problem in FShell_render:
mov [esi+eax],dx
shr edx,16
mov [esi+eax+2],dl
this proc rely in esi. Perhaps because ABI, program work here.
Quote from: HSE on August 29, 2018, 04:39:50 AM
Quote from: Magnum on August 29, 2018, 04:27:39 AM
What is ABI?
Search forum :biggrin:
The problem in FShell_render: mov [esi+eax],dx
shr edx,16
mov [esi+eax+2],dl
this proc rely in esi. Perhaps because ABI, program work here.
I did a search for ABI but found only our posts.
I have not done any assembly programming for at least 7 yrs.
So, please consider me a somewhat newbie.
Quote from: Magnum on August 29, 2018, 04:48:04 AM
I did a search for ABI but found only our posts.
From time to time is refloated that subject.
I fill esi with a valid value.
mov esi, bitmap1
Not working.
I appreciate all your help.
But I installed Masm32 and assembled one of the examples.
Ollydbg also works.
And it works great.
:t