flat assembler
Message board for the users of flat assembler.

Index > Main > MMX color replace

Author
Thread Post new topic Reply to topic
Abruzzi



Joined: 30 Sep 2019
Posts: 17
Abruzzi 30 Sep 2019, 12:41
Hello guys,

I am new to assembler and I try some basic image processing using MMX registers. (Please don't ask why MMX and not SSE or something else Rolling Eyes )

I ended up in a situation where data in registers are like below:
mm0 = 0201FFFF 04FE03FF
mm1 = 0201FFFF 0201FFFF
mm2 = 0000FFFF 0000FFFF

In mm0 I have two bitmap pixels with alpha channel and I try to replace each pixel with color 0201FFFF with color 0000FFFF. So I ended up filling mm1 with search color and mm2 with replace color and then compare double words of mm0 with mm1 to get some kind of mask for what I have to replace

Code:
pcmpeqd mm1, mm0    


mm1 = FFFFFFFF 00000000

And here I am stucked since I don't know how to replace dwords from mm0 with dwords from mm2 using the mask from mm1. Any help is much appreciated.
Post 30 Sep 2019, 12:41
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20344
Location: In your JS exploiting you and your system
revolution 30 Sep 2019, 12:53
Use the PAND and the PANDN to isolate the bits you want, and then POR to put in the replacements.

PANDN:
0201FFFF 04FE03FF source
00000000 FFFFFFFF mask (inverted by PANDN)
------------------------------
00000000 04FE03FF output-0

PAND:
FFFFFFFF 00000000 mask
0000FFFF 0000FFFF replacement
-----------------------------
0000FFFF 00000000 output-1

POR:
00000000 04FE03FF output-0
0000FFFF 00000000 output-1
-----------------------------
0000FFFF 04FE03FF result
Post 30 Sep 2019, 12:53
View user's profile Send private message Visit poster's website Reply with quote
Abruzzi



Joined: 30 Sep 2019
Posts: 17
Abruzzi 30 Sep 2019, 13:26
Thank you very much, that was clever.
Post 30 Sep 2019, 13:26
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20344
Location: In your JS exploiting you and your system
revolution 30 Sep 2019, 13:30
Abruzzi wrote:
Thank you very much, that was clever.
Yes, it is clever. But I didn't invent that. It is actually a very old technique that has been around for a very long time.
Post 30 Sep 2019, 13:30
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8354
Location: Kraków, Poland
Tomasz Grysztar 30 Sep 2019, 13:32
Are you limited to the original MMX instruction set, or is your constraint that you just need to use MMX registers? This would determine if you could use some of the later instructions, for example MASKMOVQ which could be used to selectively write pixel data from MMX register to memory, but it was introduced by SSE and therefore not available in classic MMX CPUs.
Post 30 Sep 2019, 13:32
View user's profile Send private message Visit poster's website Reply with quote
Abruzzi



Joined: 30 Sep 2019
Posts: 17
Abruzzi 30 Sep 2019, 14:17
For some reason it works pretty well for first two pixels then things get messy. Maybe if I post the code it would be easy to follow.

Code:
mov esi, dword[esp+4]                 ; ESI = pointer to Bitmap -> Scan0
                                      ; 0000FFFF 0000FFFF FFFFFFFF FFFFFFFF 0000FFFF 0000FFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 0000FFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

mov edi, dword[esp+8]                 ; EDI = pointer to a structure Info {dword NumberOfPixels; dword Color; dword Replace}
                                      ; Info -> NumberOfPixels = 16; Info -> Color = 0000FFFF; Info -> Replace = 808080FF

mov ecx, dword[edi]                   ; ECX = Info -> NumberOfPixels = 16
        
mov edx, dword[edi+4]                 ; EDX = Info -> Color
movd mm0, edx
punpckldq mm0,mm0                     ; MM0 = 0000FFFF 0000FFFF
        
mov edx, dword[edi+8]                 ; EDX = Info -> Replace
movd mm1, edx
punpckldq mm1,mm1                     ; MM1 = 808080FF 808080FF
        
_next:
pcmpeqd mm0, [esi]
movq mm2, mm0
pandn mm0, [esi]
pand mm1, mm2
por mm0, mm1
movq [esi], mm0
add esi, 8
sub ecx, 2
jnz _next
ret 8
    


I am not sure but I think add esi,8 is not the proper way to move to next two pixels.

@Tomasz yes, I am constraint to use MMX registers without SSE instructions

BTW is there any debugger that I could use to follow the code step by step?
Post 30 Sep 2019, 14:17
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20344
Location: In your JS exploiting you and your system
revolution 30 Sep 2019, 14:26
You need to protect the compare and replacement values in mm0 and mm1. After the first time through the loop they get altered and are no longer valid for the following iterations.
Post 30 Sep 2019, 14:26
View user's profile Send private message Visit poster's website Reply with quote
Abruzzi



Joined: 30 Sep 2019
Posts: 17
Abruzzi 30 Sep 2019, 14:32
This is why I tried to protect them before the loop but I forgot that they are destination registers in some instructions. Thank you very much, again.
Post 30 Sep 2019, 14:32
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.