Thread: inline ASM as a macro

  1. #16
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Dave_Sinkula
    Doesn't 6.10 of C99 mean that a #define must be one line?
    I don't think so.

    Apreprocessing directive consists of a sequence of preprocessing tokens that begins with
    a # preprocessing token that (at the start of translation phase 4) is either the first character
    in the source file (optionally after white space containing no new-line characters) or that
    follows white space containing at least one new-line character, and is ended by the next
    new-line character.140) A new-line character ends the preprocessing directive even if it
    occurs within what would otherwise be an invocation of a function-like macro.



    140) Thus, preprocessing directives are commonly called ‘‘lines’’. These ‘‘lines’’ hav e no other syntactic
    significance, as all white space is equivalent except in certain situations during preprocessing (see the
    # character string literal creation operator in 6.10.3.2, for example).
    Footnote 140 seems to say that all whitespace is considered equal, and that "lines" is just a term, not that it actually is a single line. At least that's my read on it. I don't see any reason why they'd force a multi-line macro back to one line when the text replacement occurs. Whitespace is pretty much irrelevant as far as your source code goes anyway.

    Feel free to interpret.


    Quzah.
    Hope is the first step on the road to disappointment.

  2. #17
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Backtracking a bit, C has very little to say about asm, and even less to say about __asm. And since the implication that #define could expand using newlines as whitespace is perhaps correct -- I hate trying to find that needle in the standard's haystack -- I don't think it would very well accomodate assembly instructions that require parameters, i.e.,
    Code:
    mov
    8,2
    And footnotes I don't believe are normative.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #18
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I believe what the call does is it pushes address of the 'instruction', represented by the db 'myString', to return to onto the call stack as a RET address, and the pop var gets the address of the string by popping it back off. This could be useful for shellcode. Of course, now the 'procedure' can't really return but it never was really intended to be returned to.
    Can't be. It will jmp short to afterString. The db code is never reached because there is no return. So the db line does nothing. This should be a jmp short not call short.

  4. #19
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I don't have a C standard, but I think it's safe to assume that the behaviour is equal to the C++ standard in this regard, which says (2.1.1.2):
    Each instance of a new-line character and an immediately preceding backslash character is deleted, splicing physical source lines to form logical source lines.
    (16.2) also says:
    The only white-space characters that shall appear between preprocessing tokens within a preprocessing directive (from just after the introducing # preprocessing token through just before the terminating new-line character) are space and horizontal-tab (including spaces that have replaced comments or possibly other white-space characters in translation phase 3).
    In other words, when the preprocessor reads the comment definitions, no more newlines are left. In order to have newlines in the result, it would have to insert them. Since replacement operates on the preprocessor token level, that won't happen.

    However, this is all irrelevant, because (6.1.1) just proved to me that I was wrong about labels: they don't need to start on a new line, so my entire objection to the issue was flawed.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #20
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    >> It will jmp short to afterString. The db code is never reached because there is no return. So the db line does nothing. This should be a jmp short not call short.

    It will jmp to afterString after pushing the address of the db string onto the stack as a return address, which is then immediately pop'ed back off in the afterString proc. (db is not an instruction)

  6. #21
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by CornedBee
    I don't have a C standard, but I think it's safe to assume that the behaviour is equal to the C++ standard in this regard, which says (2.1.1.2):
    C++ isn't C. They may have similar behavior in some cases, but one does not the other make.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #22
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    It will jmp to afterString after pushing the address of the db string onto the stack as a return address, which is then immediately pop'ed back off in the afterString proc. (db is not an instruction)
    Really? Well since afterString is called FIRST, how do you suppose it pushes the address BEFORE it's called? It would have to be this:

    Code:
    db 'myString',0
    call afterString
    
    ;if we don't jump here we end up in afterString which is not what we want
    jmp ElseWhere
    
    afterString:
    ;do something here
    
    ElseWhere:

  8. #23
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by quzah
    C++ isn't C. They may have similar behavior in some cases, but one does not the other make.
    Do you still have a point, or do you just want to nitpick on every word I post?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #24
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Code:
    db 'myString',0
    call afterString
    
    ;if we don't jump here we end up in afterString which is not what we want
    jmp ElseWhere
    
    afterString:
    ;do something here
    
    ElseWhere:
    Okay, the point is that it's not supposed to be proper assembly code. For example, this sort of thing is commonly seen in shellcode like this.

    Code:
    __asm 
    {
       call short afterString
       db '/bin/sh', 'X'
    
    afterString:
       pop myVar
    
       ; Replace 'X' with NULL
       ; call system(myVar)
       ; zero var
       ; call exit(var)
    }
    It does not need or want to return from the call. The point is that the call pushes a pointer to the string that can be used in the shellcode without knowing it's actual address (which could be anywhere in memory).

  10. #25
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by CornedBee
    Do you still have a point, or do you just want to nitpick on every word I post?
    Yes. To both questions. There is a Standard, and as such, it defines behaviors. Since there is a Standard, you don't "assume" it's like C++ just because that's the way C++ does it. If it's not in the Standard, then it's wrong for you to assume it is a way that it may or may not be. That was the point.

    The C++ defines how C++ works. Not C. That's the point. You're trying to "win" your argument by stating another standard. That doesn't work. C++ is not C. C is not C++. Your standard C++ is irrelevant to this discussion.


    Quzah.
    Hope is the first step on the road to disappointment.

  11. #26
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Whatever ...
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #27
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    OK, for what it's worth, the part I quoted from 2.1.1.2 is word by word identical with the C standard, 5.1.1.2.1.2. The part I quoted from 16.2 is word by word identical with 6.10.5.

    Which, considering that one of the main goals of C++ is compatibility with C, and also considering that the C++ standard contains the C standard as a normative reference, is not at all surprising.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #28
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    That's what I was looking for, a reference in the C standard. I didn't see reference to it, because I was looking specifically for macro expansion-esque notes. Thanks.

    The second point isn't worded clearly, because it's obvious that you can span multiple lines by escaping them. But I guess they mean after it's been "semi-processed", and not at the time of you writing the code itself.


    Quzah.
    Hope is the first step on the road to disappointment.

  14. #29
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by quzah
    The second point isn't worded clearly, because it's obvious that you can span multiple lines by escaping them. But I guess they mean after it's been "semi-processed", and not at the time of you writing the code itself.
    True. However, that only applies to my out-of-context quotes. Within the standard, it is very clear that by the time the second point is invoked, all newlines have been removed already - at least conceptually. (The as-if rule applies, of course.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  2. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  3. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM
  4. Inline asm
    By wavering in forum C Programming
    Replies: 2
    Last Post: 01-29-2002, 02:42 AM
  5. My graphics library
    By stupid_mutt in forum C Programming
    Replies: 3
    Last Post: 11-26-2001, 06:05 PM