Restored from previous forum. Originally posted by Danilo.
> The fact than the PB compiler can't find procedure at
> compile time has nothing to do with optimizations.
> It's simply because PBCompiler is a one pass compiler.
You can do that also with a 1-pass-compiler.
But hey, thats not a real problem.
>All the produced code is of course optimized
>(even if the coder doesn't see it).
I said "The Compiler doesnt optimize the output"
and thats true.
You want to know what i mean ??
OK, lets go:
Code: Select all
; file TEST2.PB
MessageRequester("INFO","Hello World!",0)
; end
pbcompiler.exe test2.pb /COMMENTED
Code: Select all
; result PureBasic.asm
;
; PureBasic x86 3.20 generated code
;
; (c) 2002 Fantaisie Software
;
; The header must remain intact for Re-Assembly
;
; Requester
EXTERN _ExitProcess@4
EXTERN _HeapAlloc@12
EXTERN _HeapCreate@12
EXTERN _HeapDestroy@4
EXTERN _HeapFree@12
EXTERN _GetModuleHandleA@4
;
EXTERN _PB_MessageRequester@12
EXTERN _GetModuleFileNameA@12
EXTERN _SetCurrentDirectoryA@4
EXTERN _RtlZeroMemory@8
GLOBAL _PB_Instance
GLOBAL _PBV_ExecutableType
GLOBAL _PB_FullPath
GLOBAL _PB_DDrawBase
GLOBAL _PB_DirectInput
GLOBAL _PB_DirectSound
GLOBAL _PB_MemoryBase
GLOBAL PB_Instance
GLOBAL PB_MemoryBase
GLOBAL _PB_EndFunctions
GLOBAL _PB_StringBase
GLOBAL PB_StringBase
GLOBAL _WinMain@16
;
SEGMENT .text USE32 CLASS=CODE
;
_WinMain@16
;
PUSH dword I_BSSEnd-I_BSSStart
PUSH dword I_BSSStart
CALL _RtlZeroMemory@8
CALL _GetModuleHandleA@4
MOV [_PB_Instance],eax
PUSH dword 0
CALL _GetModuleHandleA@4
MOV [_PB_Instance],eax
PUSH dword 0
PUSH dword 4000
PUSH dword 0
CALL _HeapCreate@12
MOV [PB_MemoryBase],eax
PUSH dword 500
PUSH dword _PB_FullPath
PUSH dword [_PB_Instance]
CALL _GetModuleFileNameA@12
MOV eax, _PB_FullPath
MOV ecx,eax
PB_GetPathLoop
MOV dh,[eax]
INC eax
CMP dh,'\'
JNE PB_GetPathSkip
MOV ecx,eax
PB_GetPathSkip
CMP dh,0
JNE PB_GetPathLoop
MOV byte [ecx],0
PUSH dword PB_DataSectionStart
POP dword [PB_DataPointer]
;
; InitString()
;
PUSH dword 64000
PUSH dword 8
PUSH dword [PB_MemoryBase]
CALL _HeapAlloc@12
MOV [PB_StringBase],eax
;
; MessageRequester("INFO","Hello World!",0)
PUSH dword 0
PUSH dword _S2
PUSH dword _S1
CALL _PB_MessageRequester@12
_PB_EOP
CALL _PB_EndFunctions
;
; End Of Program
;
PUSH dword [PB_MemoryBase]
CALL _HeapDestroy@4
POP ebx
PUSH dword 0
CALL _ExitProcess@4
_PB_EndFunctions
RET
;
;
PB_AllocateString
PUSH ecx
PUSH edx
MOV eax,[ecx]
CMP eax,0
JE PB_AllocateStringSkip
PUSH eax
PUSH dword 0
PUSH dword [PB_MemoryBase]
CALL _HeapFree@12
PB_AllocateStringSkip
MOV eax,[PB_StringBase]
POP edx
SUB eax,edx
PUSH edx
INC eax
PUSH eax
PUSH dword 0
PUSH dword [PB_MemoryBase]
CALL _HeapAlloc@12
POP edx
POP ecx
MOV [ecx],eax
MOV [PB_StringBase],edx
PB_AllocateStringLoop
MOV cl,[edx]
INC edx
MOV [eax],cl
INC eax
CMP cl,0
JNE PB_AllocateStringLoop
RET
;
PB_FreeString
CMP edx,0
JE PB_FreeStringEnd
PUSH eax
PUSH edx
PUSH dword 0
PUSH dword [PB_MemoryBase]
CALL _HeapFree@12
POP eax
PB_FreeStringEnd
RET
;
;
PB_CopyString
MOV ecx,[PB_StringBase]
CMP edx,0
JE PB_CopyStringEnd_Null
PB_CopyStringLoop
MOV al,[edx]
INC edx
MOV [ecx],al
INC ecx
CMP al,0
JNE PB_CopyStringLoop
DEC ecx
MOV [PB_StringBase],ecx
RET
PB_CopyStringEnd_Null
MOV [ecx],edx
RET
;
SEGMENT .data CLASS=DATA
;
_PBV_ExecutableType: dd 0
_S1: db "INFO",0
_S2: db "Hello World!",0
PB_NullString: db 0
;
SEGMENT .bss CLASS=DATA2
;
I_BSSStart
_PB_MemoryBase:
PB_MemoryBase: RESD 1
_PB_StringBase:
PB_StringBase: RESD 1
_PB_Instance:
PB_Instance: RESD 1
_PB_DDrawBase: RESD 1
_PB_DirectInput: RESD 1
_PB_DirectSound: RESD 1
PB_FPUControl: RESW 1
_PB_FullPath: RESB 500
;
ALIGNB 4
PB_DataPointer RESD 1
ALIGNB 4
I_BSSEnd
SEGMENT .data CLASS=DATA:
PB_DataSectionStart:
You dont need all that init stuff in this example.
You dont need the String stuff, you dont need _RtlZeroMemory@8,
you dont need the Path things, you dont need the Heap stuff, ...
At least 25% bull in the output.
I really dont call that optimized output, but i could live
with it. Its ~1k init-stuff, OK.
Frederic: thats not all, sorry.
Now we going deeper... and test how good
pbcompiler really is:
Code: Select all
; file TEST.pb
MessageRequester("INFO","Hello World!",0)
Procedure myBeep()
beep_(1400,300)
beep_(1000,200)
EndProcedure
Procedure consoletest()
OpenConsole()
For a = 0 To 20
PrintN("Hello World from Console")
Next a
Input()
CloseConsole()
EndProcedure
; end
pbcompiler test.pb /COMMENTED
Code: Select all
; result PureBasic.asm
;
; PureBasic x86 3.20 generated code
;
; (c) 2002 Fantaisie Software
;
; The header must remain intact for Re-Assembly
;
; Console
; Requester
EXTERN _ExitProcess@4
EXTERN _HeapAlloc@12
EXTERN _HeapCreate@12
EXTERN _HeapDestroy@4
EXTERN _HeapFree@12
EXTERN _GetModuleHandleA@4
EXTERN _Beep@8
;
EXTERN PB_CloseConsole
EXTERN PB_Input
EXTERN _PB_MessageRequester@12
EXTERN PB_OpenConsole
EXTERN PB_PrintN
EXTERN _GetModuleFileNameA@12
EXTERN _SetCurrentDirectoryA@4
EXTERN _RtlZeroMemory@8
GLOBAL _PB_Instance
GLOBAL _PBV_ExecutableType
GLOBAL _PB_FullPath
GLOBAL _PB_DDrawBase
GLOBAL _PB_DirectInput
GLOBAL _PB_DirectSound
GLOBAL _PB_MemoryBase
GLOBAL PB_Instance
GLOBAL PB_MemoryBase
GLOBAL _PB_EndFunctions
GLOBAL _PB_StringBase
GLOBAL PB_StringBase
GLOBAL _WinMain@16
;
SEGMENT .text USE32 CLASS=CODE
;
_WinMain@16
;
PUSH dword I_BSSEnd-I_BSSStart
PUSH dword I_BSSStart
CALL _RtlZeroMemory@8
CALL _GetModuleHandleA@4
MOV [_PB_Instance],eax
PUSH dword 0
CALL _GetModuleHandleA@4
MOV [_PB_Instance],eax
PUSH dword 0
PUSH dword 4000
PUSH dword 0
CALL _HeapCreate@12
MOV [PB_MemoryBase],eax
PUSH dword 500
PUSH dword _PB_FullPath
PUSH dword [_PB_Instance]
CALL _GetModuleFileNameA@12
MOV eax, _PB_FullPath
MOV ecx,eax
PB_GetPathLoop
MOV dh,[eax]
INC eax
CMP dh,'\'
JNE PB_GetPathSkip
MOV ecx,eax
PB_GetPathSkip
CMP dh,0
JNE PB_GetPathLoop
MOV byte [ecx],0
PUSH dword PB_DataSectionStart
POP dword [PB_DataPointer]
;
; InitString()
;
PUSH dword 64000
PUSH dword 8
PUSH dword [PB_MemoryBase]
CALL _HeapAlloc@12
MOV [PB_StringBase],eax
;
; MessageRequester("INFO","Hello World!",0)
PUSH dword 0
PUSH dword _S2
PUSH dword _S1
CALL _PB_MessageRequester@12
;
; Procedure myBeep()
JMP NEAR _EndProcedure0
_Procedure0
PUSH ebx
PUSH ecx
PUSH ebp
PUSH esi
PUSH edi
; beep_(1400,300)
PUSH dword 300
PUSH dword 1400
CALL _Beep@8
; beep_(1000,200)
PUSH dword 200
PUSH dword 1000
CALL _Beep@8
; EndProcedure
XOR eax,eax
_EndProcedure1
POP edi
POP esi
POP ebp
POP ecx
POP ebx
RET
_EndProcedure0
;
; Procedure consoletest()
JMP NEAR _EndProcedure2
_Procedure2
PUSH ebx
PUSH ecx
PUSH ebp
PUSH esi
PUSH edi
MOV esi,esp
SUB esp,4
MOV eax,esp
MOV edx,eax
ADD edx,4
_ClearLoop3
MOV dword [eax],0
ADD eax,4
CMP eax,edx
JNE _ClearLoop3
; OpenConsole()
CALL PB_OpenConsole
; For a = 0 To 20
MOV dword [esp+0],0
_For1
MOV eax,20
CMP eax,dword [esp+0]
JL NEAR _Next2
; PrintN("Hello World from Console")
MOV eax,dword _S3
CALL PB_PrintN
; Next a
ADD dword [esp+0],1
JMP NEAR _For1
_Next2
; Input()
PUSH dword [PB_StringBase]
CALL PB_Input
POP dword [PB_StringBase]
; CloseConsole()
CALL PB_CloseConsole
; EndProcedure
XOR eax,eax
_EndProcedure3
ADD esp,4
POP edi
POP esi
POP ebp
POP ecx
POP ebx
RET
_EndProcedure2
;
_PB_EOP
CALL _PB_EndFunctions
;
; End Of Program
;
PUSH dword [PB_MemoryBase]
CALL _HeapDestroy@4
POP ebx
PUSH dword 0
CALL _ExitProcess@4
_PB_EndFunctions
RET
;
;
PB_AllocateString
PUSH ecx
PUSH edx
MOV eax,[ecx]
CMP eax,0
JE PB_AllocateStringSkip
PUSH eax
PUSH dword 0
PUSH dword [PB_MemoryBase]
CALL _HeapFree@12
PB_AllocateStringSkip
MOV eax,[PB_StringBase]
POP edx
SUB eax,edx
PUSH edx
INC eax
PUSH eax
PUSH dword 0
PUSH dword [PB_MemoryBase]
CALL _HeapAlloc@12
POP edx
POP ecx
MOV [ecx],eax
MOV [PB_StringBase],edx
PB_AllocateStringLoop
MOV cl,[edx]
INC edx
MOV [eax],cl
INC eax
CMP cl,0
JNE PB_AllocateStringLoop
RET
;
PB_FreeString
CMP edx,0
JE PB_FreeStringEnd
PUSH eax
PUSH edx
PUSH dword 0
PUSH dword [PB_MemoryBase]
CALL _HeapFree@12
POP eax
PB_FreeStringEnd
RET
;
;
PB_CopyString
MOV ecx,[PB_StringBase]
CMP edx,0
JE PB_CopyStringEnd_Null
PB_CopyStringLoop
MOV al,[edx]
INC edx
MOV [ecx],al
INC ecx
CMP al,0
JNE PB_CopyStringLoop
DEC ecx
MOV [PB_StringBase],ecx
RET
PB_CopyStringEnd_Null
MOV [ecx],edx
RET
;
SEGMENT .data CLASS=DATA
;
_PBV_ExecutableType: dd 0
_S1: db "INFO",0
_S2: db "Hello World!",0
_S3: db "Hello World from Console",0
PB_NullString: db 0
;
SEGMENT .bss CLASS=DATA2
;
I_BSSStart
_PB_MemoryBase:
PB_MemoryBase: RESD 1
_PB_StringBase:
PB_StringBase: RESD 1
_PB_Instance:
PB_Instance: RESD 1
_PB_DDrawBase: RESD 1
_PB_DirectInput: RESD 1
_PB_DirectSound: RESD 1
PB_FPUControl: RESW 1
_PB_FullPath: RESB 500
;
ALIGNB 4
PB_DataPointer RESD 1
ALIGNB 4
I_BSSEnd
SEGMENT .data CLASS=DATA:
PB_DataSectionStart:
Booooaaahhhh!!
All procedures are still included in the output,
even if you dont need it.
You cant include a file with all your standard-procedures
in a PureBasic project.
The 1st example is 4,03k .EXE and the
2nd is 6,03k.
Both examples are only a little MessageBox
with "Hello World!" - no memory needed, no string
operations needed, no Path thing needed and the
2 procedures are not used.
Fred (no offence!), you know that this is NOT
optimized output. Everybody knows that.
Thats why i said "The PB compiler is very simple".
If you want to make a very good compiler
that can compete with C and other languages
you should make the output optimized.
The init-stuff isnt the big thing, but the
thing with the procedures is really bad.
The compiler can check easily if a procedure
is used or not, so it could include only the
needed stuff.
PureBasic is GOOD -> and most important: ITS FUN.
With some little optimizations
you could make it VERY GOOD -
better than most other compilers.
>May be I should put a useless 'disable optimizations'
>flags to let the user see them...
Well... thats your idea - just do it.
I think you understand what i´m talking about.
Beginners and people that dont know much internals
say something like
>"I trust you, without knowing what's going on in the compiler"
The programmer who knows how all the stuff works
can only laught about such comments.
As i said:
PureBasic IS good, but it could be better.
I wouldnt stay here when i think that PB is bull.
I DONT want to fight here (hi PB ), but i want
to discuss some things.
If we cant talk about some things here, we dont need
this forum - right ??
Communication is very important.
That brings me to another topic: DOUBLES.
Frederic: Many, many people asked about that,
but every time somebody is asking for doubles
you go away and hide (in the chat).
Why cant you answer this ??
I dont see a reason, so i dont understand
why you cant answer that.
Its also annoying for the user to ask again
and again - and its not good for your nerves.
Cant you simply say "PureBasic will never support
doubles" or "I´ll try to implement doubles for
PureBasic 3.5" or something like that ??
To get no answer is very bad. Million peoples
are waiting for it, and nobody knows the answer.
Remember: No offence, no fighting - only simple communication.
PEACE!
cya,
...Danilo
(registered PureBasic user)