News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

How windows handle data to be used in SSE2 ?

Started by guga, March 16, 2025, 02:47:00 AM

Previous topic - Next topic

guga

Not sure if here is the proper subforum to ask this, but....I´m giving a try on newer functions using SSE2 to gain performance, but while i was working on one of them i faced a small issue regarding how the data pass to a xmm register on windows.  I know, i know..it´s a dumb question, but i´m trying to avoid faultive errors or messages like that on windows.

Let´s say that i have a string to be passed on a xmm register. The string is let´s say, 20 bytes long stored in esi.

[MyString: B$ "123456789abcdefghijk", 0]

mov esi MyString
movups xmm0 X$esi

Ok, so far, xmm0 will hold "123456789abcdefg".

But then i want to pass the rest of it...so the remainder 4 bytes to xmm0, xmm1 or whatever other register "hijk"

Say i´ll do this do load the remainder bytes:
movups xmm1 X$esi+16

Since the string is only 20 bytes long....in theory windows should generate an error trying to load the remainder bytes, right ?

But, i have several functions that works like this, such as string lenght calculation etc - If i recall, JJ, Siekmanski etc also has this, and no error happens whatsoever.

My question is why ?

The opposite i know that is guaranteed to have an error, i mean, if i try to load the string before it´s start. Ex:

mov esi MyString
sub esi 10
movups xmm0 X$esi 

It will generate an error here right ?

But why windows successfully loads the string even if it is smaller than 16 bytes and is located after it´s start ?

Suppose the string is not loaded with virtual memory...suppose the string is located phisically inside the own app (At the very end of the .data section, for example). Shouldn´t it crash ?

Or i´m totally confused, and loading a sting like that - (Which will be truncated) is also safe since windows manage this somehow ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

jj2007

Most of the time strings are in heap memory, and there is a 16 byte or so tolerance

guga

Hi JJ

what if it is not a string ? Say it is a normal data located inside a PE and we simply point to it´s start rather than load it in memory ?  For example, say we have a chunk of data in the .data section of a PE file and we point to the very end of the .data section. If we try to use a xmm register to load this chunk will it crash if it is located16 bytes before the end of the .data section or the processor can manage this type of loading in xmm ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

NoCforMe

Wait a second: something's wrong here.
MyString: B$ "123456789abcdefghijk", 0
mov esi MyString
No can do.

ESI is a 32-bit register, right?
That means you can store at most 4 characters in it (8 bits each).

Unless you're trying to store a pointer to the string in ESI; but that's not what that mov instruction does.
You'd need to use mov esi, OFFSET MyString to get a pointer to the string.
Assembly language programming should be fun. That's why I do it.

adeyblue

You don't need to engineer 'things at the end of the data section' to give it a test

invoke VirtualAlloc, 0, 0x2000, MEM_RESERVE, PAGE_READWRITE
invoke VirtualAlloc, eax, 0x1000, MEM_COMMIT, PAGE_READWRITE
add eax, 0xff8
movups xmm0, xmmword ptr [eax]

Microsoft's Application Verifier has a mode that'll put every allocation at the end of a page next to an invalid one specifically to catch errors like this. Because it is an error, even if it seems to work. Like taking more than you should from your bank account, eventiually you'll end up overdrawn.

jj2007

Quote from: adeyblue on March 16, 2025, 03:07:43 PMBecause it is an error, even if it seems to work

Strictly speaking, yes. However, Windows is tolerant, so at least heap allocated memory allows the movups xmm0, [eax] even if eax is at the end of the string.

If Windows were less tolerant, tons of software would fail. Test it with CRT strlen:
load a 4096 byte text file into a virtualalloc'ed 4096 byte buffer, then check the length of the "string" :cool:

guga

Hi JJ

tks. Indeed, Windows is more tolerant when handling virtual memory. I was thinking in specific cases where the data is not loaded in memory on the conventional way, but pointed at a specific address inside a file or inside the PE (exe or dll) itself.

I agree that if that wouldn´t hapened tons of app will crash here and there. I askedd because i´m testing some newer routines for Instring or Binary Search using SSE2 , and in some parts of the code, the data allocated at a xmm register was beyond the end of the data. I mean, it loads 16 bytes on xmm0, but if the data on that chunk ends before the 16th byte, i notice some weird behaviour, because it was filling the remainder bytes with whatever data he found in memory and nevertheless it didn´t crashed.

I´m finishing a couple of tests i´m making on a update of SIMD_BinaryScan i posted here sometime ago and while developing the backwards version (SIMD_BinaryScanBack or any other name i´ll use later), i accidentally noticed this behaviour on the normal (forward) version.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

Quote from: NoCforMe on March 16, 2025, 02:06:57 PMWait a second: something's wrong here.
MyString: B$ "123456789abcdefghijk", 0
mov esi MyString
No can do.

ESI is a 32-bit register, right?
That means you can store at most 4 characters in it (8 bits each).

Unless you're trying to store a pointer to the string in ESI; but that's not what that mov instruction does.
You'd need to use mov esi, OFFSET MyString to get a pointer to the string.

yep, it is a pointer to the string. In RosAsm when we do things like:
MyString: B$ "123456789abcdefghijk", 0
mov esi MyString

We are loading the pointer to that variable. On the default syntax, there´s no need for tokens such as offset of dword ptr etc. You can, however emulate this with the preparser token.

To load the content (Equivalent to dword ptr), all you need to do is use the token "$" preceeded by the token related to the size of the data. ex:
D$ for Dwords
W$ for words
B$ for byte
T$ for tenbyte
X$ for SSE
F$ for float
Q$ for qword
R$ for Real
etc

Ex:
MyString: B$ "123456789abcdefghijk", 0
mov esi D$MyString ; will load the 1st dword of the string MyString
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com