Page 1 of 1
assembly question
Posted: Sun Jul 01, 2012 8:01 am
by basil99
Hi!
Have this simple assembly code in my PB programm
Code: Select all
EnableASM
PUSHAD
MOV esi, S
MOV edi, D
MOV ecx, DrawWidth
FDloop:
MOV eax, [esi]
ADD esi, 4
MOV [edi], eax
ADD edi, 4
DEC ecx
JNZ FDloop
POPAD
DisableASM
try to compile and get this error messge:
Purebasic assembler error: JNZ FDloop error : undefined symbol 'FDloop'.
Whats wrong here ? any ideas ? Plese point my stupid head )
Thanks
Re: assembly question
Posted: Sun Jul 01, 2012 9:37 am
by J. Baker
!FDloop:
Re: assembly question
Posted: Sun Jul 01, 2012 12:44 pm
by wilbert
JNZ l_fdloop
Is also a possibility
When you reference a label, you must put the prefix 'l_' before the name. This is because PureBasic add a 'l_' before a BASIC label to avoid conflit with internal labels. The label need to be referenced in lowercase when using the inlined ASM.
Re: assembly question
Posted: Mon Jul 02, 2012 9:14 am
by basil99
Thanks for replies.
l_FDloop don't work, but !FDloop does.
Anyway, I need further assistance.
This assembly code:
Code: Select all
EnableASM
PUSHAD
MOV esi, S
MOV edi, D
MOV ecx, DrawWidth
!FDloop:
MOV eax, [esi]
ADD esi, 4
MOV [edi], eax
ADD edi, 4
DEC ecx
JNZ FDloop
POPAD
DisableASM
planned to be the assembly version of this PB code, that works fine:
Code: Select all
For x = 1 To DrawWidth
B = PeekI( S )
S = S + 4
PokeI( D, B )
D = D + 4
next x
So, PB code works, Assembly code crashed. Whats wrong ? Thanks
Re: assembly question
Posted: Mon Jul 02, 2012 9:31 am
by Thorium
If your code is in a procedure you mess up the stack index of the local variables with pushad. Thats why it crashes.
Try this:
Code: Select all
!push esi
!push edi
!mov esi, [p.v_S+8]
!mov edi, [p.v_D+8]
!mov ecx, [p.v_DrawWidth+8]
!FDloop:
!mov eax, [esi]
!add esi, 4
!mov [edi], eax
!add edi, 4
!dec ecx
!jnz FDLoop
!pop edi
!pop esi
Re: assembly question
Posted: Mon Jul 02, 2012 10:36 am
by basil99
Thorium wrote:If your code is in a procedure you mess up the stack index of the local variables with pushad. Thats why it crashes.
Try this:
Code: Select all
!push esi
!push edi
!mov esi, [p.v_S+8]
!mov edi, [p.v_D+8]
!mov ecx, [p.v_DrawWidth+8]
!FDloop:
!mov eax, [esi]
!add esi, 4
!mov [edi], eax
!add edi, 4
!dec ecx
!jnz FDLoop
!pop edi
!pop esi
Thanks, Thorium, tried it and get this error message:
!mov esi, [p.v_S+8] - error: undefined symbol 'p.v_S+8'
as for code, don't catch what you mean with "procedure". Code skeleton looks like this:
Code: Select all
S1 = Calculate( S1 )
D1 = Calculate( D1 )
DrawWidth = Calculate( DrawWidth )
DrawHeight = Calculate( DrawHeight )
Sstep = Calculate( Sstep )
Dstep = Calculate( Dstep )
for y = 1 to DrawHeight
S = S1
D = D1
for x = 1 to DrawWidth
Code, we're talking about
next x
S = S + Sstep
D = D + Dstep
next y
sure, its a part of a procedure for a DLL i try to code )
Re: assembly question
Posted: Mon Jul 02, 2012 10:56 am
by wilbert
Code: Select all
EnableASM
MOV eax, S
MOV edx, D
MOV ecx, DrawWidth
PUSH ebx
!FDloop:
MOV ebx, [eax]
ADD eax, 4
MOV [edx], ebx
ADD edx, 4
DEC ecx
JNZ FDloop
POP ebx
DisableASM
Re: assembly question
Posted: Mon Jul 02, 2012 11:09 am
by Thorium
basil99 wrote:
Thanks, Thorium, tried it and get this error message:
!mov esi, [p.v_S+8] - error: undefined symbol 'p.v_S+8'
as for code, don't catch what you mean with "procedure". Code skeleton looks like this:
The undefined symbol is actualy without the +8 and means it's a global variable. for global variables use only v_ not p.v_, p.v_ is only for local variables.
With procedure i mean if the code is located inside a procedure and uses local variables. Because local variables are on the stack, the stack index for them shifts if you push something to the stack. So you must add the number of bytes to the variable pointer that was been pushed to the stack.
Re: assembly question
Posted: Mon Jul 02, 2012 11:37 am
by basil99
Stiil confused (
Seems, need to explain more clear what i'm doing.
1. Third party code prepares a raw RGBA image ( actually BGRA ). I know image adress, image Width and Height, and image Pitch = len of one pixels line. Pitch in general is not equal to Width*4. Also, a destination adress is known, where i need to put "processed" image.
2. So, I decide to create a DLL for this, that would make all this job. Fiest step is just to copy source data into destination. Processing is another step, not significant to talk about here
3. Dll code is:
Code: Select all
ProcedureDLL ImageProcessing( Width, Height, SourceAdress, DestAdress, Pitch )
S1 = SourceAdress
D1 = DesrAdress
DrawWidth = Width
DrawHeight = Height
Sstep = Pitch
Dstep = Pitch
for y = 1 to DrawHeight
S = S1
D = D1
for x = 1 to DrawWidth
B = PeekI( S )
S = S + 4
PokeI( D, B )
D = D + 4
next x
S = S + Sstep
D = D + Dstep
next y
EndProcedure
and this works perfect. But asembly not (
Re: assembly question
Posted: Mon Jul 02, 2012 12:26 pm
by Thorium
Dont know how i should explain it differently.
But as i wrote, this works:
Code: Select all
ProcedureDLL ImageProcessing( Width, Height, SourceAdress, DestAdress, Pitch )
S1 = SourceAdress
D1 = DesrAdress
DrawWidth = Width
DrawHeight = Height
Sstep = Pitch
Dstep = Pitch
For y = 1 To DrawHeight
S = S1
D = D1
!push esi
!push edi
!mov esi, [p.v_S+8]
!mov edi, [p.v_D+8]
!mov ecx, [p.v_DrawWidth+8]
!FDLoop:
!mov eax, [esi]
!add esi, 4
!mov [edi], eax
!add edi, 4
!dec ecx
!jnz FDLoop
!pop edi
!pop esi
S = S + Sstep
D = D + Dstep
Next y
EndProcedure
Re: assembly question
Posted: Mon Jul 02, 2012 12:44 pm
by basil99
Great ! It works.
and I need to learn syntax better.
Thanks a lot for this
Re: assembly question
Posted: Mon Jul 02, 2012 12:54 pm
by Pupil
If you're only moving data from one place to another, why not use the built in 'CopyMemory()' function instead?
If pitch is same for source and destination I think something like this would work OK:
Code: Select all
CopyMemory(SourceAdress, DestAdress, (width*4+pitch)*height)
Re: assembly question
Posted: Mon Jul 02, 2012 2:22 pm
by basil99
Pupil wrote:If you're only moving data from one place to another, why not use the built in 'CopyMemory()' function instead?
If pitch is same for source and destination I think something like this would work OK:
Code: Select all
CopyMemory(SourceAdress, DestAdress, (width*4+pitch)*height)
Good idea, mate. I have smth more complex to do:
1) I need to make some operations with source image, like filter, effects etc
2) destination area may be an another image, smaller or bigger or equal then source one. So, some clipping is required ( omitted here )
3) Quick timing brings me the following : asm vesion 2.5-3 times faster then native PB peek/poke )
Re: assembly question
Posted: Thu Jul 05, 2012 5:03 pm
by Psychophanta
PB does allow to define variables, but does not allow to define labels inside a EnableASM-DisableASM block.
This looks like a clear bug to me.
Re: assembly question
Posted: Sun Jul 08, 2012 12:55 pm
by ultralazor
Even better.. why not just use PB? Maybe for your users sake since you don't know how a stack frame works?