• Welcome to Valhalla Legends Archive.
 

Lots of NOPs?

Started by MyndFyre, November 30, 2004, 12:48 AM

Previous topic - Next topic

MyndFyre

I was taking a look at WoW.exe with drivehappy, and I noticed this:


00401130   . E9 0B000000    JMP WoW.00401140
00401135     90             NOP
00401136     90             NOP
00401137     90             NOP
00401138     90             NOP
00401139     90             NOP
0040113A     90             NOP
0040113B     90             NOP
0040113C     90             NOP
0040113D     90             NOP
0040113E     90             NOP
0040113F     90             NOP


I don't do a lot of assembly analysis; the only stuff that I have done was 8086 and 80286 stuff with a 16-bit DOS debugger.  I was curious as to why there are so many NOPs -- is it used for big block transfers or for alignment in some way?  I could see that, but -- alignment -- why are there more than 3 at any given time?

Thanks!
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Arta

Seems there's a JMP right before them. Does that code ever get executed?

Adron

It's not that uncommon to see functions aligned to 16 bytes. Diablo 1 and Starcraft are or used to be that way. Some compilers use INT 3 instead of NOP to fill out. IIRC it has to do with cache lines, ensuring that as much of the function as possible fits inside the first fetch to cache.

iago

I've seen it done with "int 3" only in debug versions.  I would imagine it's so, if you pooch something up and end up jumping there, you'll get a debug break rather than a random crash.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


MyndFyre

Quote from: Arta[vL] on November 30, 2004, 01:12 AM
Seems there's a JMP right before them. Does that code ever get executed?
No, of course, and I mentioned that I thought it might be for alignment, but as I said, I was surprised at the quantity of NOPs as opposed to them being there at all.

Quote from: Adron on November 30, 2004, 05:56 AM
It's not that uncommon to see functions aligned to 16 bytes. Diablo 1 and Starcraft are or used to be that way. Some compilers use INT 3 instead of NOP to fill out. IIRC it has to do with cache lines, ensuring that as much of the function as possible fits inside the first fetch to cache.

Thanks Adron!  That makes sense.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Skywing

You might also find the compiler aligning the start of a loop using nops (or other nop-like instructions depending on how many bytes of padding are required, such as lea esp, dword ptr [esp+0]).

Adron

Quote from: Skywing on December 01, 2004, 02:00 AM
You might also find the compiler aligning the start of a loop using nops (or other nop-like instructions depending on how many bytes of padding are required, such as lea esp, dword ptr [esp+0]).

Do you have any examples of loop start aligning occurring in practise?

Skywing

Quote from: Adron on December 01, 2004, 09:04 AM
Quote from: Skywing on December 01, 2004, 02:00 AM
You might also find the compiler aligning the start of a loop using nops (or other nop-like instructions depending on how many bytes of padding are required, such as lea esp, dword ptr [esp+0]).

Do you have any examples of loop start aligning occurring in practise?
The first example I found offhand was:

text:00409433                 mov     al, byte ptr [esp+224h+RootPathName]
.text:00409437                 test    al, al
.text:00409439                 lea     esi, [esp+224h+RootPathName]
.text:0040943D                 jz      short loc_409493
.text:0040943F                 nop
.text:00409440
.text:00409440 loc_409440:                             ; CODE XREF: sub_409350+141j
.text:00409440                 push    esi             ; lpRootPathName
.text:00409441                 call    ebp ; GetDriveTypeA
.text:00409443                 cmp     eax, 5


..where it's aligning the loop to 00409440.

Adron

And that one doesn't seem like a particularly worthwhile optimization? Calling an API inside the loop should slow it down enough... Nothing in the compiler to pick out what loops might be better to optimize?

Skywing

Quote from: Adron on December 01, 2004, 07:00 PM
And that one doesn't seem like a particularly worthwhile optimization? Calling an API inside the loop should slow it down enough... Nothing in the compiler to pick out what loops might be better to optimize?
Well, that was from bnupdate, and judging from the things I've seen in it I think the programmer had the compiler set to "maximally stupid" while building it.  It was the first example I ran into.