• The Old New Thing

    Can an x64 function repurpose parameter home space as general scratch space?


    We saw some time ago that the x64 calling convention in Windows reserves space for the register parameters on the stack, in case the called function wants to spill them. But can the called function use the memory for other purposes, too?

    You sort of already know the answer to this question. Consider this function:

    void testfunction(int a)
     a = 42;

    How would a naïve compiler generate code for this function?

        sub rsp, 8 ;; realign the stack
        ;; spill all register parameters into home locations
        mov [rsp+0x10], rcx
        mov [rsp+0x18], rdx
        mov [rsp+0x20], r8
        mov [rsp+0x28], r9
        ;; a = 42
        mov [rsp+0x10], 42
        ;; return
        add rsp, 8 ;; clean up local frame

    Observe that after spilling the register parameters into their home locations onto the stack, the function modified the local variable, which updated the value in the home location.

    Since a function can arbitrarily modify a parameter, you can see that a function is therefore allowed to arbitrarily modify a parameter's home location. At which point you can see that an optimizing compiler might choose an arbitrary value completely unrelated to the parameter.

    Our test function has only one parameter. What about the other three home registers?

    The caller is responsible for allocating space for parameters to the callee, and must always allocate sufficient space for the 4 register parameters, even if the callee doesn't have that many parameters.

    A function can therefore treat those 32 bytes as bonus free play. The rationale behind those 32 bytes is that it gives you a place to spill your inbound register parameters so that they will be adjacent to the stack-based parameters. (We saw how the naïve compiler took advantage of this by not trying to be clever in its function prologue and simply spilling all register parameters whether it needs them or not.)

    Nevertheless, you are free to use them for whatever purpose you like, and if you're looking at heavily-optimized code, you'll probably find that the compiler found all sorts of clever things it can do with them. For example, a common trick is to use them to save the nonvolatile registers that the function locally uses to hold the corresponding parameter!

    (Did this article look familiar? Turns out I covered this article a few years ago, but I'm senile and accidentally repeated a topic. And since I put so much effort into writing it, I'm going to make you suffer through it, even though it's a repeat. Hey, television programs repeat during the summer.)

  • The Old New Thing

    Once you know something can be done, doing it is much easier


    Unfortunately, I don't remember the name of the star of this story, but I'm told that there was a notable mathematician who believed the Perfect Graph Conjecture to be false and spent many years trying to prove it one way or another.

    Meanwhile, another mathematician (presumably László Lovász) announced that he had found a proof (in the affirmative).

    Upon hearing the news that the open question had been resolved, the first mathematician was able to produce a proof within 90 minutes.

    Once again showing that it's much easier to do something once you know it can be done.

  • The Old New Thing

    The conversations backstage at computer Go tournaments


    Steve Rowe linked to an essay on why computers can't play Go well even though they've mastered other "difficult" games like chess. I was reminded of a description I received of what happens backstage at computer Go tournaments (i.e., tournaments that pit Go-playing computers against each other). ("Backstage" is a bit of a misnomer, of course; since the contestants are computers, you can talk all you want as loud as you want without worrying about distracting the players.)

    At computer Go tournaments, the programmers are like parents watching their children compete in a hockey game where they've only just barely learned how to skate. It's not so much a matter of who plays better as it is a matter of who sucks less. One programmer will lean over to the other and say something like "I hope my program realizes its left-hand-side is vulnerable before your program takes advantage of it."

  • The Old New Thing

    Puzzling out the upsell-o-meter


    As I noted before, many grocery stores in the United States have a printer next to the cash register which prints out coupons customized to your purchases. Here's a purchase and the accompanying coupon. What is the story behind this pairing?

    Purchased: Diapers for newborn baby.
    Coupon: Save 75 cents on ice cream.

    Bonus chatter: While waiting in line, I read the warning label on the diapers. It went on for quite a bit, but one part triggered my "I wonder what lawsuit led to this warning" sensor: "Like most articles of clothing, XYZ brand diapers will burn if exposed to flame." Did somebody say, "Oh no, there's a fire, what will I do? I know, I'll smother the fire with my baby's diapered bottom!"

  • The Old New Thing

    Luxurifying the camping experience in a different direction


    Some time ago, I noted the increasing luxurification of camping, where people with more money than sense decide to go through the camping experience without building any of the character that comes with it.

    But that's not the only direction luxurification has moved. Unwilling to accept that "getting there is half the fun", some people take chartered planes to and from summer camp. Stick it out for the punch line in the final sentence of the article.

  • The Old New Thing

    Why is my icon being drawn at the wrong size when I call DrawIcon?


    Some time ago I had a problem with icon drawing. When I tried to draw an icon with Draw­Icon it ended up being drawn at the wrong size. A call to Get­Icon­Info confirmed that the icon was 48×48, but it drew at 32×32.

    The answer is documented in a backwards sort of way in the Draw­Icon­Ex function, which says at the bottom,

    To duplicate DrawIcon (hDC, X, Y, hIcon), call DrawIconEx as follows:

    DrawIconEx (hDC, X, Y, hIcon, 0, 0, 0, NULL,

    Aha, if you use Draw­Icon, then the icon size is ignored and it is drawn with DI_DEFAULT­SIZE.

    The fix, therefore, was to switch to the Draw­Icon­Ex function so I could remove the DI_DEFAULT­SIZE flag, thereby permitting the icon to be drawn at its actual size.

    - DrawIcon(hdc, pt.x, pt.y, hico);
    + DrawIconEx(hdc, pt.x, pt.y, hico, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);

    A bonus quirk of the DI_DEFAULT­SIZE flag (and therefore of the Draw­Icon function) is that the drawing is done at the default icon size, even if you asked it to draw a cursor.

  • The Old New Thing

    Inserting as many layers between the message and reality as possible


    Some time ago I received a message that described a situation that was "based on a reality-based scenario."

    Wow, how many layers away from reality can you get?

    It wasn't a real scenario.

    It wasn't a reality-based scenario.

    It was based on a reality-based scenario.

    Then again, I'm just adding to the problem. I'm writing a message about a situation based on a reality-based scenario...

  • The Old New Thing

    What's the deal with that alternate form for menu item template separators?


    We saw last time that you can specify a separator in a menu item template by specifying zero for everything, even though technically you're supposed to pass MFT_SEPARATOR for the flags. What's the deal with that alternate form for menu item template separators?

    This goes back to the early days of the InsertMenu function (and its friends like AppendMenu and ModifyMenu). In the Before Time, the way you specified a separator was to add a null pointer. Not a null string (a string with no characters, consisting only of the null terminator), but an actual null pointer.

    AppendMenu(hmenu, MF_STRING, 0, NULL);

    The recommended way of adding a separator is, of course, to use MF_SEPARATOR, but this old-fashioned method is still supported for backward compatibility. The alternate form of the menu item template for separators is just a throwback to the days when this "old style" of adding a separator was in fact the only style.

  • The Old New Thing

    Raymond misreads flyers, episode 2: It Takes You


    As part of a new phase in Microsoft's continuing recycling efforts, the recycling program got a new motto. The new motto was not announced with any fanfare. Rather, any recycling-related announcement had the new motto at the top as part of the letterhead.

    The new motto: It Takes You.

    I had trouble parsing this at first. To me, it sounded like the punch line to a Yakov Smirnoff joke.

    Episode 1.

  • The Old New Thing

    Kindergarten writing exercise from my niece


    When my niece was in kindergarten, a regular classroom assignment was for students to write a few sentences about something happening in their lives. For one of the assignments, my niece wrote the following:

    My auntie has a baby in her tumy. If it is a boy I will call him Kevin. If it is a grl I will call her Alula.

    We have no idea where the name "Alula" came from.

    The baby turned out to be a girl, but her aunt chose a different name.

    My niece did not hold up her end of the bargain and call her new cousin "Alula".

    Update: Upon further reflection, I think the proposed boy's name was "Derik", not Kevin. Not important to the story, but included for completeness.

Page 370 of 441 (4,410 items) «368369370371372»