• The Old New Thing

    The history of calling conventions, part 1

    • 27 Comments
    The great thing about calling conventions on the x86 platform is that there are so many to choose from!

    In the 16-bit world, part of the calling convention was fixed by the instruction set: The BP register defaults to the SS selector, whereas the other registers default to the DS selector. So the BP register was necessarily the register used for accessing stack-based parameters.

    The registers for return values were also chosen automatically by the instruction set. The AX register acted as the accumulator and therefore was the obvious choice for passing the return value. The 8086 instruction set also has special instructions which treat the DX:AX pair as a single 32-bit value, so that was the obvious choice to be the register pair used to return 32-bit values.

    That left SI, DI, BX and CX.

    (Terminology note: Registers that do not need to be preserved across a function call are often called "scratch".)

    When deciding which registers should be preserved by a calling convention, you need to balance the needs of the caller against the needs of the callee. The caller would prefer that all registers be preserved, since that removes the need for the caller to worry about saving/restoring the value across a call. The callee would prefer that no registers be preserved, since that removes the need to save the value on entry and restore it on exit.

    If you require too few registers to be preserved, then callers become filled with register save/restore code. But if you require too many registers to be preserved, then callees become obligated to save and restore registers that the caller might not have really cared about. This is particularly important for leaf functions (functions that do not call any other functions).

    The non-uniformity of the x86 instruction set was also a contributing factor. The CX register could not be used to access memory, so you wanted to have some register other than CX be scratch, so that a leaf function can at least access memory without having to preserve any registers. So BX was chosen to be scratch, leaving SI and DI as preserved.

    So here's the rundown of 16-bit calling conventions:

    All
    All calling conventions in the 16-bit world preserve registers BP, SI, DI (others scratch) and put the return value in DX:AX or AX, as appropriate for size.

    C (__cdecl)
    Functions with a variable number of parameters constrain the C calling convention considerably. It pretty much requires that the stack be caller-cleaned and that the parameters be pushed right to left, so that the first parameter is at a fixed position relative to the top of the stack. The classic (pre-prototype) C language allowed you to call functions without telling the compiler what parameters the function requested, and it was common practice to pass the wrong number of parameters to a function if you "knew" that the called function wouldn't mind. (See "open" for a classic example of this. The third parameter is optional if the second parameter does not specify that a file should be created.)

    In summary: Caller cleans the stack, parameters pushed right to left.

    Function name decoration consists of a leading underscore. My guess is that the leading underscore prevented a function name from accidentally colliding with an assembler reserved word. (Imagine, for example, if you had a function called "call".)

    Pascal (__pascal)
    Pascal does not support functions with a variable number of parameters, so it can use the callee-clean convention. Parameters are pushed from left to right, because, well, it seemed the natural thing to do. Function name decoration consists of conversion to uppercase. This is necessary because Pascal is not a case-sensitive language.

    Nearly all Win16 functions are exported as Pascal calling convention. The callee-clean convention saves three bytes at each call point, with a fixed overhead of two bytes per function. So if a function is called ten times, you save 3*10 = 30 bytes for the call points, and pay 2 bytes in the function itself, for a net savings of 28 bytes. It was also fractionally faster. On Win16, saving a few hundred bytes and a few cycles was a big deal.

    Fortran (__fortran)
    The Fortran calling convention is the same as the Pascal calling convention. It got a separate name probably because Fortran has strange pass-by-reference behavior.

    Fastcall (__fastcall)
    The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

    Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.

    Okay, those are the 16-bit calling conventions I remember. Part 2 will discuss 32-bit calling conventions, if I ever get around to writing it.

  • The Old New Thing

    Don't trust the return address

    • 17 Comments
    Sometimes people ask, "So I know how to get my return address [use the _ReturnAddress() intrinsic]; how do I figure out what DLL that return address belongs to?"

    Beware.

    Even if you figure out which DLL the return address belongs to [use Get­Module­Handle­Ex(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)], that doesn't mean that that is actually the DLL that called you.

    A common trick is to search through a "trusted" DLL for some code bytes that coincidentally match ones you (the attacker) want to execute. This can be something as simple as a "retd" instruction, which are quite abundant. The attacker then builds a stack frame that looks like this, for, say, a function that takes two parameters.

    trusted_retd
    hacked parameter 1
    hacked parameter 2
    hacker_code_addr
    

    After building this stack frame, the attacker then jumps to the start of the function being attacked.

    The function being attacked looks at the return address and sees trusted_retd, which resides in a trusted DLL. It then foolishly trusts the caller and allows some unsafe operation to occur, using hacked parameters 1 and 2. The function being attacked then does a "retd 8" to return and clean the parameters. This transfers control to the trusted_retd, which performs a simple retd, which now gives control to the hacker_code_addr, and the hacker can use the result to continue his nefarious work.

    This is why you should be concerned if somebody says, "This code verifies that its caller is trusted..." How do they know who the caller really is?

  • The Old New Thing

    How to stop delivery of telephone books

    • 29 Comments

    Like many of you (I suspect), I don't use the paper telephone book. If I want to look something up, I go online. Yet every year I get a dozen different telephone books. I don't like them because a telephone book sitting on my front porch screams, "Rob this house! Nobody's home!" Besides, it's a waste of paper.

    So for the past few years I've been trying to stop delivery of all the telephone books. It's harder than you think.

    The first hurdle is figuring out what the "please take me off your mailing list" number is. Because they sure don't advertise it.

    I've discovered that the best way to get through to somebody who can take you off the list is to call the "How to order more copies of this wonderful telephone directory."

    Note: WorldPages added another wrinkle to the procedure. You see, they misprinted their own telephone number. Why anybody would voluntarily pay money to be listed by a telephone directory company that can't even get their own phone number right is beyond me.

    You have to be polite but firm when dealing with these people. Qwest is particularly tricky. I had called last year to stop delivery of all three of their phone books (they have three!), but in June another one showed up. I called them and they confirmed, "Yes, I see that we have a zero on your account, I don't know what happened. Let me try again."

    Aside: Why does Qwest want my telephone number to stop delivery of my telephone book? They deliver the book to a house, not to a telephone.

    Anyway, so that seems to keep the telephone book delivery gnomes at bay, until December, when yet another Qwest telephone book arrives at my doorstep. So I call again.

    "Yes, we have you marked as 'do not deliver'."

    "So why did I get one?"

    "This wasn't one of our standard phone books. This was a promotional phone book."

    Aha, so when you say "Do not deliver" it doesn't actually mean, "Do not deliver." It just means "Don't deliver the one that I am specifically complaining about." But there's this double-secret phone book delivery list that you have to specifically ask to be removed from, and we're not going to tell you about it until you ask.

    "Please remove me from the promotional phone book delivery list as well."

    "I'm sorry, I can't do that. There is no way for us to enter that in our computers." Always blame the computers. One response to "Our computer can't do that" I haven't yet resorted to is "Well, then I guess you'll have to do it by hand.")

    "Who delivers the promotional phone books?"

    "We contract that out to a local delivery company."

    "Can I talk to them?"

    "Hang on a second."

    <wait>>

    "Okay, I can fill out a form so you don't receive promotional phone books either." (Aha, so she is going to do it by hand.)

    "Thank you. Good-bye."

    We'll see how long this lasts. I predict May.
  • The Old New Thing

    College football commercialized? What ever gave you that idea?

    • 1 Comments
    This has got to be some sort of record for "Longest official name of a sponsored college football game": The Gaylord Hotels Music City Bowl Presented by Bridgestone, which proclaims that "the Gaylord Hotels Music City Bowl Presented By Bridgestone is Nashville's Holiday Tradition".
  • The Old New Thing

    People with almanacs may be terrorists, FBI warns

    • 6 Comments
    The FBI has apparently released a bulletin advising law enforcement officers to be on the alert for people with almanacs: They might be terrorists.
  • The Old New Thing

    What's the difference between CreateMenu and CreatePopupMenu?

    • 16 Comments
    CreateMenu creates a horizontal menu bar, suitable for attaching to a top-level window. This is the sort of menu that says "File, Edit", and so on.

    CreatePopupMenu creates a vertical popup menu, suitable for use as a submenu of another menu (either a horizontal menu bar or another popup menu) or as the root of a context menu.

    If you get the two confused, you can get strange menu behavior. Windows on rare occasions detects that you confused the two and converts as appropriate, but I wouldn't count on Windows successfully reading your mind.

    There is no way to take a menu and ask it whether it is horizontal or vertical. You just have to know.

    Answers to other questions about menus:

    When a window is destroyed, its menu is also destroyed. When a menu is destroyed, the entire menu tree is destroyed. (All its submenus are destroyed, all the submenu's submenus, etc.) And when you destroy a menu, it had better not be the submenu of some other menu. That other menu would have an invalid menu as a submenu!

    If you remove a submenu from its parent, then you become responsible for destroying it, since it no longer gets destroyed automatically when the parent is destroyed.

    It is legal for a menu to be a submenu of multiple parent menus. Be extra careful when you do this, however, because if one of the parents is destroyed, it will destroy the submenu with it, leaving the other parent with an invalid submenu.

    And finally: The menu nesting limit is currently 25 on Windows XP. That may change in the future, of course. (As with window nesting, Windows 95 let you go ahead and nest menus all you wanted. In fact, you could go really evil and create an infinite loop of menus. You crashed pretty quickly thereafter, of course...)

  • The Old New Thing

    At least the Danes know how to count

    • 17 Comments

    Even though Danish is impossible for me to pronounce, I do appreciate their stubborn resistance to decimalization. The number 71 is (I hope I get this right) "en og halvfjerdsindstyve", literally, "one and half-four-times-twenty", or more commonly, just "en og halvfjerds". (Those familiar with other Germanic languages recognize "half-four" as meaning "three and a half".)

    (I hope the Danes out there realize that my previous remarks about Danish were all in fun. I'm just fascinated with languages, especially those in the Germanic branch.)

  • The Old New Thing

    What's with those blank taskbar buttons that go away when I click on them?

    • 41 Comments

    Sometimes you'll find a blank taskbar button that goes away when you click on it. What's the deal with that?

    There are some basic rules on which windows go into the taskbar. In short:

    • If the WS_EX_APPWINDOW extended style is set, then it will show (when visible).
    • If the window is a top-level unowned window, then it will show (when visible).
    • Otherwise it doesn't show.

    (Though the ITaskbarList interface muddies this up a bit.)

    When a taskbar-eligible window becomes visible, the taskbar creates a button for it. When a taskbar-eligible window becomes hidden, the taskbar removes the button.

    The blank buttons appear when a window changes between taskbar-eligible and taskbar-ineligible while it is visible. Follow:

    • Window is taskbar-eligible.
    • Window becomes visible ? taskbar button created.
    • Window goes taskbar-ineligible.
    • Window becomes hidden ? since the window is not taskbar-eligible at this point, the taskbar ignores it.

    Result: A taskbar button that hangs around with no window attached to it.

    This is why the documentation also advises, "If you want to dynamically change a window's style to one that doesn't support visible taskbar buttons, you must hide the window first (by calling ShowWindow with SW_HIDE), change the window style, and then show the window."

    Bonus question: Why doesn't the taskbar pay attention to all windows as they come and go?

    Answer: Because that would be expensive. The filtering out of windows that aren't taskbar-eligible happens inside USER32 and it then notifies the taskbar (or anybody else who has installed a WH_SHELL hook) via one of the HSHELL_* notifications only if a taskbar-eligibie window has changed state. That way, the taskbar code doesn't get paged in when there's nothing for it to to.
  • The Old New Thing

    "Beam me up" is not yet recognized

    • 2 Comments

    How soon before this becomes standard equipment at Star Trek conventions?

    Vocera Communications Unveils Wearable, Instant Voice Communications Application

    "Enterprise environments are looking for applications that leverage their investment in wireless communication technologies and increase employee efficiency," ...

    Some of the basic calling features include:

    • Call by name, "Call Bob Thomas."
    • Call by function, "Call a cardiologist."
    • Call by specific location, "Locate a clerk in gardening." ...
    The Vocera Communications System

    Vocera Communications Badge is a wearable device that weighs less than two ounces and can easily be clipped to a shirt pocket or worn on a lanyard. ...

    The Vocera Communications Badge is controlled using natural spoken language. To initiate a conversation with Jim and Mary, for example, the user would simply say, "Conference Jim Anderson and Mary Guscia."

  • The Old New Thing

    Another privacy policy that isn't very private

    • 6 Comments
    Today I read the privacy policy for Nuveen Investment Advisors. I like this part:
    We do not disclose any nonpublic personal information about you to anyone, except as permitted by law.

    "Except as permitted by law". How reassuring. Is it really necessary to have an official policy promising that that you won't break the law? And actually stating that they promise to follow the law on this specific issue raises the question, "So are they willing to break the law with regard to other issues?"

    This sentence basically means, "We reserve the right to disclose nonpublic personal information about you to the fullest extent permitted by law."

    In particular, later in that paragraph, it states that

    ... we may disclose the information we collect, as described above, to companies that perform administrative or marketing services on our behalf...

    In other words, "We may disclose nonpublic information about you to people who will try to sell you stuff."

    All the regulations about privacy disclosure statements hasn't actually secured anybody's privacy, since the regulations only require disclosure; they don't require that they actually do anything to protect your privacy.

Page 407 of 426 (4,251 items) «405406407408409»