The MASM Forum

General => The Workshop => Topic started by: NoCforMe on November 09, 2024, 06:53:17 PM

Title: Code to align to 32 bits
Post by: NoCforMe on November 09, 2024, 06:53:17 PM
Small li'l tidbit here: in my current program I needed to align some data to a 32-bit (DWORD) boundary. I'm dealing with BMP bitmaps here and needed to determine the padding necessary for lines that didn't fall on such a boundary.

I came up with the following code:
      MOV    EAX, <line length>
      NEG    EAX                       ;Flip bits arithmetically
      AND    EAX, 11B                  ;Isolate 2 low bits
      MOV    padding, EAX              ;and Bob's your uncle

which works out to:
   length AND 11B   padding
          0            0
          1            3
          2            2
          3            1

I actually figured this out myself. I know there are other ways to skin this particular cat, and maybe even some cleverer ones. (Would it be possible to do it in only two instructions?) So I'm wondering what other methods people have come up with.

Micro$oft has this tricky technique that I still haven't quite figured out how it works:
    pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits + 31) & ~31) /8
                                  * pbmi->bmiHeader.biHeight;
Title: Re: Code to align to 32 bits
Post by: Vortex on November 09, 2024, 08:12:25 PM
Hi NoCforMe,

Reading your code from this message :

; Calculate actual bitmap size including any needed padding:
    MOV    EAX, BMPwidth
    MUL    BMPbpp
    ADD    EAX, 31
    AND    EAX, NOT 31
    SHR    EAX, 3
    MUL    BMPheight
    MOV    actualBMPsize, EAX

https://masm32.com/board/index.php?msg=126368 (https://masm32.com/board/index.php?msg=126368)

;  Bitmap size = (( BITMAPINFO.bmiHeader.biWidth * BITMAP.bmPlanes * BITMAP.bmBitsPixel + 31 ) & ~31 ) / 8
;                 * BITMAPINFO.bmiHeader.biHeight

;  ~31 = NOT 31 = NOT 00011111 = 11100000

;  NOT 00011111 = 11100000 => -32


The count of bits is aligned to the next 32-bit boundry. ( +31 trick )

This line does the 32-bit alignment :

    AND    EAX, NOT 31  ;  AND EAX,-32
A quick test :

Test 1
x=0  ,  x AND -32 = 0
x=1  ,  x AND -32 = 0
x=2  ,  x AND -32 = 0
x=3  ,  x AND -32 = 0
x=4  ,  x AND -32 = 0
.
.
x=29  ,  x AND -32 = 0
x=30  ,  x AND -32 = 0
x=31  ,  x AND -32 = 0
x=32  ,  x AND -32 = 32
x=33  ,  x AND -32 = 32
x=34  ,  x AND -32 = 32
.
.
x=62  ,  x AND -32 = 32
x=63  ,  x AND -32 = 32
x=64  ,  x AND -32 = 64
x=65  ,  x AND -32 = 64
x=66  ,  x AND -32 = 64
x=67  ,  x AND -32 = 64

Test 2
x=0  ,  (x+31) AND -32 = 0
x=1  ,  (x+31) AND -32 = 32
x=2  ,  (x+31) AND -32 = 32
x=3  ,  (x+31) AND -32 = 32
x=4  ,  (x+31) AND -32 = 32
.
.
x=29  ,  (x+31) AND -32 = 32
x=30  ,  (x+31) AND -32 = 32
x=31  ,  (x+31) AND -32 = 32
x=32  ,  (x+31) AND -32 = 32
x=33  ,  (x+31) AND -32 = 64
x=34  ,  (x+31) AND -32 = 64
.
.
x=62  ,  (x+31) AND -32 = 64
x=63  ,  (x+31) AND -32 = 64
x=64  ,  (x+31) AND -32 = 64
x=65  ,  (x+31) AND -32 = 96
x=66  ,  (x+31) AND -32 = 96
x=67  ,  (x+31) AND -32 = 96
Title: Re: Code to align to 32 bits
Post by: sinsi on November 09, 2024, 09:18:13 PM
Quote from: Vortex on November 09, 2024, 08:12:25 PMThe count of bits is aligned to the next 32-bit boundry. ( +31 trick )

This line does the 32-bit alignment :

Code Select Expand
    AND    EAX, NOT 31  ;  AND EAX,-32
Isn't that 32 byte alignment?

;EAX has an address
  add eax,3
  and eax,not 3
Title: Re: Code to align to 32 bits
Post by: zedd151 on November 09, 2024, 11:28:36 PM
Quote from: sinsi on November 09, 2024, 09:18:13 PMIsn't that 32 byte alignment?
:biggrin:  this made me chuckle.
So does the OP need 32 bit alignment, or 32 byte alignment? A big difference. I think I know the answer.  :cool:
Title: Re: Code to align to 32 bits
Post by: NoCforMe on November 10, 2024, 04:59:06 AM
So my way is simpler. I win!

(This technique could be adapted for 32-byte alignment.)

Not this:
Quote from: Vortex on November 09, 2024, 08:12:25 PMReading your code from this message :

; Calculate actual bitmap size including any needed padding:
    MOV    EAX, BMPwidth
    MUL    BMPbpp
    ADD    EAX, 31
    AND    EAX, NOT 31
    SHR    EAX, 3
    MUL    BMPheight
    MOV    actualBMPsize, EAX

https://masm32.com/board/index.php?msg=126368 (https://masm32.com/board/index.php?msg=126368)

Yikes; my old code comes back to haunt me ...
Title: Re: Code to align to 32 bits
Post by: Vortex on November 10, 2024, 05:57:21 AM
Hello,

Same method used to align the stack inside a procedure ( 64-bit coding ) :

and rsp,-16
Title: Re: Code to align to 32 bits
Post by: sinsi on November 10, 2024, 07:52:24 AM
Quote from: Vortex on November 10, 2024, 05:57:21 AMHello,

Same method used to align the stack inside a procedure ( 64-bit coding ) :

and esp,-16
That would clear the high 32 bits of RSP though...ouch
and rsp,-16
and sp,-16
and spl,-16
Title: Re: Code to align to 32 bits
Post by: Vortex on November 10, 2024, 07:55:47 AM
Hi Sinsi,

Sorry for the typo, statement corrected above : and rsp,-16
Title: Re: Code to align to 32 bits
Post by: mineiro on November 11, 2024, 10:20:51 AM
Quote from: NoCforMe on November 10, 2024, 04:59:06 AMSo my way is simpler. I win!

What did you get? More ego?
Next time, stop posting lots of messages with technical errors, this is for you and zedd151. Waiting for the "gang of 4" to come and protect members of the bubble, but not criticize him as they have done in the past. So, to be fair and honest, I'm here.
A simple topic, just see in binary and see patterns. An and with 1111 will do the rest, wow,. For a person who owns an oscilloscope this would be trivial,...
Title: Re: Code to align to 32 bits
Post by: NoCforMe on November 11, 2024, 10:30:07 AM
Quote from: mineiro on November 11, 2024, 10:20:51 AM
Quote from: NoCforMe on November 10, 2024, 04:59:06 AMSo my way is simpler. I win!

What did you get? More ego?

It was a, it was a, a joke, son.
What, do I have to use smileys to indicate that?

QuoteNext time, stop posting lots of messages with technical errors, this is for you and zedd151. Waiting for the "gang of 4" to come and protect members of the bubble, but not criticize him as they have done in the past. So, to be fair and honest, I'm here.
A simple topic, just see in binary and see patterns. An and with 1111 will do the rest, wow,. For a person who owns an oscilloscope this would be trivial,...

What technical errors did I commit here? None that I can see.

I like my method, and it seems to be simpler than the other ones I've seen.

Those patterns you mention aren't obvious to me.
And what does an oscilloscope have to do with it? I'm curious, because I do own one (an old Tektronix). How can this be used to illustrate bit alignment?
Title: Re: Code to align to 32 bits
Post by: mineiro on November 11, 2024, 10:47:11 AM
Quote from: NoCforMe on November 11, 2024, 10:30:07 AMdoes an oscilloscope have to do with it? I'm curious,
Square waves? I'm wasting my time.
Title: Re: Code to align to 32 bits
Post by: NoCforMe on November 11, 2024, 11:01:23 AM
OK, what specifically about square waves? I'm quite familiar with them, but have no idea what you're getting at here.
Title: Re: Code to align to 32 bits
Post by: zedd151 on November 11, 2024, 12:43:11 PM
Quote from: mineiro on November 11, 2024, 10:20:51 AMNext time, stop posting lots of messages with technical errors, this is for you and zedd151.
???
What are you even talking about?  :undecided:

"gang of four"?
Gang of Four - CCP (https://en.wikipedia.org/wiki/Gang_of_Four)
I am not now, or have I ever been, a member of the Chinese communist party.  :tongue:  I do own Chinese products though, of varying quality.  :smiley:

Or did you mean "gang of four" design patterns?
Gang of Four - Design Patterns (https://www.digitalocean.com/community/tutorials/gangs-of-four-gof-design-patterns)
I have no clue what that is, I googled and it was one of the responses, besides the one mentioned above.  :rolleyes:

Title: Re: Code to align to 32 bits
Post by: NoCforMe on November 11, 2024, 12:44:44 PM
That's what I'm trying to figure out.
Maybe they had too much to drink.
Title: Re: Code to align to 32 bits
Post by: TimoVJL on November 11, 2024, 08:32:24 PM
What is Data Alignment? (http://www.songho.ca/misc/alignment/dataalign.html)
Title: Re: Code to align to 32 bits
Post by: jj2007 on November 11, 2024, 11:13:56 PM
Quote from: NoCforMe on November 09, 2024, 06:53:17 PMI came up with the following code:
Code Select Expand
      MOV    EAX, <line length>
      NEG    EAX                       ;Flip bits arithmetically
      AND    EAX, 11B                  ;Isolate 2 low bits
      MOV    padding, EAX              ;and Bob's your uncle
Does the 11B actually assemble without the "h"?
Title: Re: Code to align to 32 bits
Post by: sinsi on November 11, 2024, 11:31:18 PM
Binary?
Title: Re: Code to align to 32 bits
Post by: NoCforMe on November 13, 2024, 09:21:39 AM
That code works like a charm for aligning both 256-color BMP data (1 byte/pixel) and 16-color data (2 pixels/byte), but it doesn't work at all on 2-color data, with 8 pixels/byte. Here's the scheme for determining padding in that case:

# bits AND 1111B    padding
-----------------------------
      1 - 8           3
      8 - 16          2
     17 - 24          1
     25 - 32          0
(the last case includes # bits AND 11111B = 0)

So I ended up getting the padding by brute force:

; Get padding for 2 colors:
MOV EAX, BMPwidth ;Width in pixels
AND EAX, 11111B
JZ pad0 ;If 0, no padding needed.
CMP EAX, 8
JBE pad3
CMP EAX, 16
JBE pad2
CMP EAX, 24
JBE pad1
pad0: XOR EAX, EAX
JMP SHORT setpad
pad1: MOV EAX, 1
JMP SHORT setpad
pad2: MOV EAX, 2
JMP SHORT setpad
pad3: MOV EAX, 3

setpad: MOV Padding, EAX

Not very elegant but it works.

Can anyone think of a wickedly clever scheme that does this computationally, without conditional tests? I couldn't come up with anything. Guess I'm just not that clever.
Title: Re: Code to align to 32 bits
Post by: TimoVJL on November 13, 2024, 10:00:03 AM
DELETED as had a bug for OP's example
Title: Re: Code to align to 32 bits
Post by: NoCforMe on November 13, 2024, 01:07:02 PM
Timo, do you even bother reading articles before posting links to them?
That article had nothing--nothing at all--that addressed, let alone answered, my question. It was a complete waste of time, both on my part and on yours.

Sheesh. I'm starting to lose confidence in other humans having enough common sense to know when to post something they think is "helpful" and when to simply STFU.
Title: Re: Code to align to 32 bits
Post by: _japheth on November 13, 2024, 04:39:42 PM
Quote from: NoCforMe on November 13, 2024, 01:07:02 PMTimo, do you even bother reading articles before posting links to them?
That article had nothing--nothing at all--that addressed, let alone answered, my question. It was a complete waste of time, both on my part and on yours.

Hmmmm - the article at least clears the terminology (answer 1): the number of bytes between 2 rows of a .bmp file, called the stride and, OTOH, the number of bits per pixel . If I understand correctly, it's only the stride that needs alignment ( to a dword, meaning that the address of the first pixel of a row must have its lowest 2 bits cleared ). The bits per pixel value shouldn't matter at all.
Title: Re: Code to align to 32 bits
Post by: NoCforMe on November 13, 2024, 05:23:48 PM
I understand the layout of BMP bitmap data very well; that's not the issue. The article didn't tell me anything I didn't already know.

Yes, the "stride" is the important thing here. And it is totally dependent on bits per pixel.

Let's take a 24- or 32-BPP bitmap: there's no alignment adjustment needed here, because each pixel falls on a 32-bit boundary.

With lower BPP bitmaps, alignment becomes an issue: the next step down from 24 BPP is 8 BPP, a 256-color bitmap with a palette. Here the pixels are bytes, so obviously we might need to do some adjustment to land on a DWORD boundary. Same with 4 BPP, a 16-color bitmap (2 pixels per byte).

My question, if anyone remembers it, has to do with the lowest form of BMP, 1 BPP, AKA black and white. Here each bit is a pixel. So obviously alignment is an issue. Let's say your bitmap is 12 pixels wide (a bit small, but whatever): that means we need to pad each row with 2 bytes (12 bits fits in a 16-bit word). The stride then becomes 4 (the shortest actual row for a 1 BPP bitmap). The stride is simply the actual length of a row of pixels, including padding: it's what you have to add to the address of a row to get to the next row.

I gave my method how to figure the padding (and from that the stride) for a 1 BPP bitmap. What I was asking for was a more elegant solution, not a primer in BMP structure.
Title: Re: Code to align to 32 bits
Post by: sinsi on November 13, 2024, 05:43:39 PM
Quote from: NoCforMe on November 13, 2024, 05:23:48 PMLet's take a 24- or 32-BPP bitmap: there's no alignment adjustment needed here, because each pixel falls on a 32-bit boundary.
No, a 24-bit pixel is 3 bytes but in a BMP tle line is aligned to 32-bits.

You need to calculate how many bits are in one line and align the end to the next DWORD.
Title: Re: Code to align to 32 bits
Post by: jj2007 on November 13, 2024, 06:11:03 PM
Quote from: sinsi on November 11, 2024, 11:31:18 PMBinary?

Oops, right :thumbsup:
Title: Re: Code to align to 32 bits
Post by: NoCforMe on November 13, 2024, 06:31:44 PM
Quote from: sinsi on November 13, 2024, 05:43:39 PM
Quote from: NoCforMe on November 13, 2024, 05:23:48 PMLet's take a 24- or 32-BPP bitmap: there's no alignment adjustment needed here, because each pixel falls on a 32-bit boundary.
No, a 24-bit pixel is 3 bytes but in a BMP tle line is aligned to 32-bits.

You need to calculate how many bits are in one line and align the end to the next DWORD.

Sorry, right: 24 BPP would require padding under some circumstances.

There's also a 16 BPP format that I've never seen nor dealt with. That would be, what? 65K colors. Non-indexed (no palette). I think. Never dealt with that format either.
Title: Re: Code to align to 32 bits
Post by: _japheth on November 13, 2024, 06:57:03 PM
Quote from: NoCforMe on November 13, 2024, 05:23:48 PMI gave my method how to figure the padding (and from that the stride) for a 1 BPP bitmap. What I was asking for was a more elegant solution, not a primer in BMP structure.

According to MS in https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader (https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader) the formula is:

stride = ((((biWidth * biBitCount) + 31) & ~31) >> 3);
biSizeImage = abs(biHeight) * stride;
Title: Re: Code to align to 32 bits
Post by: NoCforMe on November 13, 2024, 07:18:07 PM
I guess that's the universal formula (works for all BPPs). Maybe I should just use that ...

Still need to calculate padding for my app, but that's easily done.