I've pinched your bit set/get/clear code.

@dioxin and other gurus.
We tyros could probably do with some education on playing with the stack.
For example, I think PureBasic allows EAX,ECX,EDX to get clobbered but the other registers must be preserved. So if calling an imported proc, how do do this nicely? For example (fasm):
Code: Select all
format MS COFF
public fillWith
section '.text' code readable executable
; Copy 'pattern' of 'size' bytes to 'dest', 'count' times
; this destroys EAX, ECX, EDX (which shouldn't hurt PureBasic)
fillWith: ; Dest, Pattern, Count, Size
pop eax ; return address
pop edx ; 'Size' to DX (think about pop cx; jcxz @exit; xchg cx,dx)
pop ecx ; 'Count' to CX (could jcxz @exit)
pop esi ; Pattern
pop edi ; Dest
mov ebx,esi ; So we can keep restoring it
push eax ; restore return addy
cld ; go forward
@outerLoop:
push ecx ; Save 'Count'
mov ecx, edx ; Use 'Size'
mov esi,ebx ; point to 'Pattern' start
rep movsb ; copy 'Pattern' to next bit of 'Dest'
pop ecx ; 'Count' to counter
loop @outerLoop ; counter not zero, redo
@exit:
ret
What would be a really good way to get the parameters, ensure the return address was in the right place, and also ensure the other registers were safely preserved?
Also if it was not imported but stuck in a procedure.
Edit:
This does work, but not sure how safe it is:
Code: Select all
format MS COFF
public fillWith
section '.text' code readable executable
; Copy 'pattern' of 'size' bytes to 'dest', 'count' times
; this destroys EAX, ECX, EDX (which shouldn't hurt PureBasic)
; however it also destroys EBX, ESI, EDI (not good)
fillWith: ; Dest, Pattern, Count, Size
push ebx ; Save for pure
push esi
push edi
mov edx,[esp + 28] ; Dest
mov ecx,[esp + 24] ; Pattern
mov esi,[esp + 20] ; Count
mov edi,[esp + 16] ; Size
mov ebx,esi ; So we can keep restoring it
cld ; go forward
@outerLoop:
push ecx ; Save 'Count'
mov ecx, edx ; Use 'Size'
mov esi,ebx ; point to 'Pattern' start
rep movsb ; copy 'Pattern' to next bit of 'Dest'
pop ecx ; 'Count' to counter
loop @outerLoop ; counter not zero, redo
@exit:
pop edi ; Restore for pure
pop esi
pop ebx
ret
Code: Select all
Import "path\to\myPatternFill.obj"
fillWith.l(dest.l,patt.l,times.l,size.l) As "fillWith"
EndImport
d.s = "AbcdAbcdAbcdAbcdAbcdAbcd"
p.s = "1234"
fillWith(@d,@p,3,4) ; half fill
Debug d