I noticed you did not preserve the contents of the registers ebx,edi, and esi. I know they are not considered volatile. Are they reset by PureBasic before returning from the procedure? Does that make your procedure a reliable and safe one considering these things? I'm simply curious.Thorium wrote:Just wrote a "real" Assembler procedure. real = pure assembler, no PB in procedure.
SwapMemory()
Re:
Re: Re:
I don't know. ^^Demivec wrote:I noticed you did not preserve the contents of the registers ebx,edi, and esi. I know they are not considered volatile. Are they reset by PureBasic before returning from the procedure? Does that make your procedure a reliable and safe one considering these things? I'm simply curious.Thorium wrote:Just wrote a "real" Assembler procedure. real = pure assembler, no PB in procedure.
Just check the asm output of PB, i never did.
But i think purebasic saves and restores registers in procedures, because i allways put my asm code in procedures and never save registers and never had a problem with it. But i did get problems if i mixed up asm and PB code. Thats why i allways put it in procedures. Well registers are not a problem but stack is. So you have to fix the stack if you mess around with it.
Re: SwapMemory()
All registers except eax, ecx and edx must always be preserved, else you may end up with wrong expression results in the caller.
Re: SwapMemory()
Ok, seems i must update some of my procedures. ^^Trond wrote:All registers except eax, ecx and edx must always be preserved, else you may end up with wrong expression results in the caller.
Can some one tell me why the first parameter on x64 is on rsp+48?
On x86 it is on esp+4 which makes sense. 4 bytes for the return address.
For what are the 40 bytes of stack used on x64?
Updated SwapMemoryASM3 x86 and x64.
Code: Select all
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Procedure MemorySwapASM3(*src, *dst, len.i)
!push esi
!push edi
!mov esi,[esp+12]
!mov edi,[esp+16]
!mov ecx,[esp+20]
!push ecx
!shr ecx,2
!align 4
!MemorySwapASM3_LoopStart1:
!cmp ecx,0
!je MemorySwapASM3_LoopEnd1
!mov eax,[esi]
!mov edx,[edi]
!mov [esi],edx
!mov [edi],eax
!add esi,4
!add edi,4
!dec ecx
!jmp MemorySwapASM3_LoopStart1
!MemorySwapASM3_LoopEnd1:
!pop ecx
!and ecx,3
!MemorySwapASM3_LoopStart2:
!cmp ecx,0
!je MemorySwapASM3_LoopEnd2
!mov al,[esi]
!mov dl,[edi]
!mov [esi],dl
!mov [edi],al
!inc esi
!inc edi
!dec ecx
!jmp MemorySwapASM3_LoopStart2
!MemorySwapASM3_LoopEnd2:
!pop edi
!pop esi
ProcedureReturn #True
EndProcedure
CompilerElse
Procedure MemorySwapASM3(*src, *dst, len.i)
!push rsi
!push rdi
!mov rsi,[rsp+64]
!mov rdi,[rsp+72]
!mov rcx,[rsp+80]
!push rcx
!shr rcx,3
!align 4
!MemorySwapASM3_LoopStart1:
!cmp rcx,0
!je MemorySwapASM3_LoopEnd1
!mov rax,[rsi]
!mov rdx,[rdi]
!mov [rsi],rdx
!mov [rdi],rax
!add rsi,8
!add rdi,8
!dec rcx
!jmp MemorySwapASM3_LoopStart1
!MemorySwapASM3_LoopEnd1:
!pop rcx
!and rcx,7
!MemorySwapASM3_LoopStart2:
!cmp rcx,0
!je MemorySwapASM3_LoopEnd2
!mov al,[rsi]
!mov dl,[rdi]
!mov [rsi],dl
!mov [rdi],al
!inc rsi
!inc rdi
!dec rcx
!jmp MemorySwapASM3_LoopStart2
!MemorySwapASM3_LoopEnd2:
!pop rdi
!pop rsi
ProcedureReturn #True
EndProcedure
CompilerEndIf
Re: SwapMemory()
Because x64 mode was made by monkeys.Can some one tell me why the first parameter on x64 is on rsp+48?
Re: SwapMemory()
> For what are the 40 bytes of stack used on x64?
On x64 you have to provide stack space for the up to 4 register parameters when calling a function (this is for vararg support mainly). PB allocates this space beforehand so it does not have to do it for every further call. The remaining 8 bytes are for alignment iirc.
Just use the "p.v_variable" notation to address parameters instead of the fixed offsets and you don't have to care about this:
http://www.purebasic.com/documentation/ ... edasm.html
Btw, x64 has more volatile registers. You should be able to do it without needing to save any registers:
http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
Note that all this is Windows only. Linux x64 has a different ABI.
On x64 you have to provide stack space for the up to 4 register parameters when calling a function (this is for vararg support mainly). PB allocates this space beforehand so it does not have to do it for every further call. The remaining 8 bytes are for alignment iirc.
Just use the "p.v_variable" notation to address parameters instead of the fixed offsets and you don't have to care about this:
http://www.purebasic.com/documentation/ ... edasm.html
Btw, x64 has more volatile registers. You should be able to do it without needing to save any registers:
http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
Note that all this is Windows only. Linux x64 has a different ABI.
quidquid Latine dictum sit altum videtur
Re: SwapMemory()
Thank you for that interesting information.freak wrote: On x64 you have to provide stack space for the up to 4 register parameters when calling a function (this is for vararg support mainly). PB allocates this space beforehand so it does not have to do it for every further call. The remaining 8 bytes are for alignment iirc.
The problem is that i have to save registers. The only way i know doing that is pushing them on the stack which will change the stack addresses of the parameter variables.freak wrote: Just use the "p.v_variable" notation to address parameters instead of the fixed offsets and you don't have to care about this:
http://www.purebasic.com/documentation/ ... edasm.html
This is not working, and it should not work. ^^
Code: Select all
Global Test1.i
Global Test2.i
Procedure Test(Param1.i, Param2.i)
!push esi
!push edi
!mov esi,[p.v_Param1]
!mov edi,[p.v_Param2]
!mov [v_Test1], esi
!mov [v_Test2], edi
!pop edi
!pop esi
EndProcedure
Test(123, 456)
Debug Test1
Debug Test2
Yes i know them but don't used them a lot. Will change this. ^^freak wrote: Btw, x64 has more volatile registers. You should be able to do it without needing to save any registers:
http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
But it's not solving the problem for x86. Well it's not realy a problem that a simple calculator can not solve. ^^
Re: SwapMemory()
> The problem is that i have to save registers.
Just add your additional offset to the location:
Just add your additional offset to the location:
Code: Select all
!mov esi,[p.v_Param1+8]
!mov edi,[p.v_Param2+8]quidquid Latine dictum sit altum videtur
Re: SwapMemory()
Ah, that is possible. Thank you.freak wrote:> The problem is that i have to save registers.
Just add your additional offset to the location:Code: Select all
!mov esi,[p.v_Param1+8] !mov edi,[p.v_Param2+8]
Re: SwapMemory()
Ok, updated the swap memory procedure for the last time, i hope. ^^
Should be save to use now. x64 version don't use the stack anymore.
Should be save to use now. x64 version don't use the stack anymore.
Code: Select all
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Procedure MemorySwapASM3(*src, *dst, len.i)
!push esi
!push edi
!mov esi,[p.p_src+8]
!mov edi,[p.p_dst+8]
!mov ecx,[p.v_len+8]
!push ecx
!shr ecx,2
!align 4
!MemorySwapASM3_LoopStart1:
!cmp ecx,0
!je MemorySwapASM3_LoopEnd1
!mov eax,[esi]
!mov edx,[edi]
!mov [esi],edx
!mov [edi],eax
!add esi,4
!add edi,4
!dec ecx
!jmp MemorySwapASM3_LoopStart1
!MemorySwapASM3_LoopEnd1:
!pop ecx
!and ecx,3
!MemorySwapASM3_LoopStart2:
!cmp ecx,0
!je MemorySwapASM3_LoopEnd2
!mov al,[esi]
!mov dl,[edi]
!mov [esi],dl
!mov [edi],al
!inc esi
!inc edi
!dec ecx
!jmp MemorySwapASM3_LoopStart2
!MemorySwapASM3_LoopEnd2:
!pop edi
!pop esi
ProcedureReturn #True
EndProcedure
CompilerElse
Procedure MemorySwapASM3(*src, *dst, len.i)
!mov r8,[p.p_src]
!mov r9,[p.p_dst]
!mov rcx,[p.v_len]
!mov r10,rcx
!shr rcx,3
!align 4
!MemorySwapASM3_LoopStart1:
!cmp rcx,0
!je MemorySwapASM3_LoopEnd1
!mov rax,[r8]
!mov rdx,[r9]
!mov [r8],rdx
!mov [r9],rax
!add r8,8
!add r9,8
!dec rcx
!jmp MemorySwapASM3_LoopStart1
!MemorySwapASM3_LoopEnd1:
!and r10,7
!MemorySwapASM3_LoopStart2:
!cmp r10,0
!je MemorySwapASM3_LoopEnd2
!mov al,[r8]
!mov dl,[r9]
!mov [r8],dl
!mov [r9],al
!inc r8
!inc r9
!dec r10
!jmp MemorySwapASM3_LoopStart2
!MemorySwapASM3_LoopEnd2:
ProcedureReturn #True
EndProcedure
CompilerEndIf


