Out of Range for 'And'

Bare metal programming in PureBasic, for experienced users
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Out of Range for 'And'

Post by Michael Vogel »

Hi, I try to do a little bit tuning and am happy about around 20% more speed for a routine doing some shade effetcs in X86 assembler now.

I see, that I am getting older, because the 8 bit (6502, 8088) and 16 bit (68000) era was perfect for me and I am stumbling around with 32 bit (see code below), but 64 bit is to much for me :lol:
I tried to convert my routine to 64 bit by replacing all eax to rax, which I was able to do after a while... but how to deal with the error in the !And rax,$FF000000 line?

Code: Select all

Procedure CustomShadowHeavyDarken(Source,Destination)

	EnableASM
	CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
		!mov eax,[p.v_Source]
		!And eax,$FF
		!shl eax,24
		!CMP eax,[p.v_Destination]
		!ja done.l_customshadowheavydarken
		!mov eax,[p.v_Destination]
		!and eax,$FF000000
		!done.l_customshadowheavydarken:
		!or eax,[v_ColorIconShadow]
	CompilerElse
		!mov rax,[p.v_Source]
		!And rax,$FF
		!shl rax,24
		!CMP rax,[p.v_Destination]
		!ja done.l_customshadowheavydarken
		!mov rax,[p.v_Destination]
		!and rax,$FF000000
		!done.l_customshadowheavydarken:
		!or rax,[v_ColorIconShadow]
	CompilerEndIf
	DisableASM
	ProcedureReturn

EndProcedure
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Out of Range for 'And'

Post by Keya »

it compiles fine (PBWin64) and your '!and rax,$FF000000" is perfectly valid (it compiles to "!db 0x48, 0x25, 0x00, 0x00, 0x00, 0xFF" if curious) -- are you sure you're not trying to compile with PB32? (hey it is the weekend afterall) :) strange it didnt complain about the other ones though!
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Out of Range for 'And'

Post by Michael Vogel »

yep, a strange weekend...

Here's a longer version of the code, hopefully it will show the error message now...

Code: Select all

; Define

	;DisableDebugger

	#IconTemp=0
	#ColorOpaque=$FF000000

	Global ColorIconShadow
	Global CustomRed
	Global CustomGreen
	Global CustomBlue
	Global CustomColor

	#X=400
	#Y=400

; EndDefine

Procedure CustomShadowHeavyDarken(x,y,Source,Destination)

	EnableASM
	CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
		!mov eax,[p.v_Source]
		!And eax,$FF
		!shl eax,24
		!CMP eax,[p.v_Destination]
		!ja done.l_customshadowheavydarken
		!mov eax,[p.v_Destination]
		!and eax,$FF000000
		!done.l_customshadowheavydarken:
		!or eax,[v_ColorIconShadow]
	CompilerElse
		!mov rax,[p.v_Source]
		!And rax,$FF
		!shl rax,24
		!CMP rax,[p.v_Destination]
		!ja done.l_customshadowheavydarken
		!mov rax,[p.v_Destination]
		!and rax,$FF000000
		!done.l_customshadowheavydarken:
		!or rax,[v_ColorIconShadow]
	CompilerEndIf
	DisableASM
	ProcedureReturn

	;ProcedureReturn ColorIconShadow | uMax((Source&$FF)<<24,Destination&$FF000000)

EndProcedure
Procedure Main()

	Protected x,y,t,z


	OpenWindow(0,0,0,#X,#Y, "-", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ImageGadget(1,0,0,#X,#Y,0)

	CreateImage(1,400,400,32,#PB_Image_Transparent)
	CreateImage(2,400,400,32,#PB_Image_Transparent)

	CreateImage(0,100,100,32)

	ColorIconShadow=$808080

	StartDrawing(ImageOutput(2))
	x=20
	y=320
	DrawingMode(#PB_2DDrawing_CustomFilter)
	CustomFilterCallback(@CustomShadowHeavyDarken())
	DrawImage(ImageID(#IconTemp),x,y)
	StopDrawing()

	StartDrawing(ImageOutput(1))
	DrawAlphaImage(ImageID(2),0,0)
	StopDrawing()


	SetGadgetState(1,ImageID(1))

	Repeat
		Select WaitWindowEvent()
		Case #PB_Event_CloseWindow,#WM_CHAR
			End
		EndSelect
	ForEver

EndProcedure

Main()
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Out of Range for 'And'

Post by Keya »

hah, yes I do get the error now - i didnt before because although i was on Win64 i was running PB32 at the time (SEE what i mean about coding on the weekend!?). Im not sure why fasm is complaining about that, but just replace the !and line with "!db 0x48,0x25,0x00,0x00,0x00,0xFF", which i obtained from x64dbg
Ok im going to make some iced coffee now to ensure this doesn't happen again
btw youre working with 32bits rgb/a vals so although you need to address it via rax you still might only need to be working with eax, might even have problems if using full rax but im not sure, just thinking out loud!
Helle
Enthusiast
Enthusiast
Posts: 178
Joined: Wed Apr 12, 2006 7:59 pm
Location: Germany
Contact:

Re: Out of Range for 'And'

Post by Helle »

The error message is correct. "AND Register,Imm32" is CPU-intern sign-extended to 64-bits. Imm64 is not exist (15-Bytes-Rule). A good Compiler/Assembler gives this message.
You must use

Code: Select all

!mov rdx,$FF000000 ;or another free register
!and rax,rdx
@Keya: This is not a good idea :) :

Code: Select all

X.q
!mov rax,$FFF000000
;!and rax,$FF000000
!db 0x48,0x25,0x00,0x00,0x00,0xFF
!mov [v_X],rax
Debug Hex(X)  ;you expect $FF000000, but... AND-value (32-bit) is sign-extended to 64-bits!
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Out of Range for 'And'

Post by Michael Vogel »

That hurts, when using callbacks for custom filter, it seems that only eax can be used without side effects - so I do get strange results here when rdx will be used as well.

A horrible workaround, I shift the register two times to get rid of the problem - I'm quite sure, the 64 bit version will be very slow (must check that now)...

...now everything got even more complicated, the routine seems to calculate correct results, but when using the custom filter, the graphics look weird (and the 64 bit version runs slower than the 32 bit routine) :twisted:
Post Reply