Using Inline or External Assembler with Xcode ?

Discussion in 'Mac Programming' started by Elhardt, Sep 21, 2013.

  1. Elhardt macrumors newbie

    Sep 21, 2013
    I've been writing a combination of C and assembly code for many years in many different compilers (Consolair C, Think C, MPW, Code Warrior, Visual C), either using inline assembly if it was available, or an external assembler. Now I come to Xcode and have hit a wall.

    Xcode is a massively bloated and confusing thing and doesn't seem to provide a single document or example of how to do either inline assembly using clean Intel syntax (not that god awful hideous ATT syntax placed in printf like statements), nor how to use an external assembler with Xcode, such as NASM, which comes with Xcode.

    There's a build option in Xcode that says Codewarrior Style Inline Assembly, but the Xcode editor doesn't like it when I type in Codewarrior style assembly, and just dumps out errors if I try to build/run the app.

    Someone online mentioned the compiler option: -fasm-blocks, but of course gives no info on where compiler options like that can be entered into Xcode.

    There's an Intel ".intel_syntax noprefix" setting too, but again, no clue as to where that's supposed to be placed, nor does that necessarily get rid of the all the extraneous surrounding nonsense like ("add eax,ebx\n\t); and allow a simple, add eax,ebx, syntax instead.

    There's no info given on how to use an external assembler with Xcode, or link in files generated by one, nor how to pass variables and pointers between C and assembly.

    So what's the deal with Xcode? They dump a big pile and stuff on my hard drive and don't explain how to use it. Where does one go to find information like this, or some examples that step a person through the process of using assembly code in C?

    Thanks for any advice.
  2. ArtOfWarfare macrumors G3


    Nov 26, 2007
    I don't often use assembly, but if I ever wanted to, I'd probably write in C files and just use the asm(); function everywhere.
  3. Elhardt thread starter macrumors newbie

    Sep 21, 2013
    I'm trying to figure out if Xcode has an acceptable way to do inline assembly using some form of asm() or _asm{}. That's why I was also asking about the inline asm Codewarrior style. But so far all I see is the ugly-ass kind of unacceptable and incomprehensible mess like this:

    __asm__ __volatile__ (“movw %w2,%0\n\t” \
    “movw %w1,2+%0\n\t” \
    “rorl $16,%1\n\t” \
    “movb %b1,4+%0\n\t” \
    “movb %3,5+%0\n\t” \
    “movb $0,6+%0\n\t” \
    “movb %h1,7+%0\n\t” \
    “rorl $16,%1” \
    : “=o”(*(n))
    : “q” (addr), “ri”(limit), “i”(type))

    or this:

    asm("int $0x3");
    asm("mov 4%0,%%eax"::"m"(x));
    asm("movss 4%0,%%xmm1"::"m"(f));
    asm("fld 4%0"::"m"(fa));

    or even this bastardized Intel syntax:

    asm(".intel_syntax noprefix\n"
    "int 3\n"
    "mov eax, [x+4]\n"
    "movss xmm1,[f+4]\n"
    "fld [fa+4]\n"

    When what's needed is something like below which virtually every other compiler I've used can do, which is fast to type in, easy to read, easy to edit, is the standard way to program in Intel assembly, and can be pasted from code already written on the PC:

    int 3
    mov eax, [x+4]
    movss xmm1,[f+4]
    fld [fa+4]

    And this may mean being forced to use an external assembler like NASM. But I can't find info on how to use it with Xcode. I'd like to think that one other person in the entire world may have gone through this same problem and solved it.
  4. ExitToShell macrumors newbie

    Sep 21, 2013
    Here's a link.

    It's kinda outdated since Apple has moved on to the LLVM compiler. Which is referenced right in the included Xcode developer documentation. Which is hidden away in the Help menu under "Xcode user guide" or in that window that opens by default with the section labeled "Xcode user guide."

    I typed in 'assembler' in the search query and got the current LLVM compiler info.
  5. ArtOfWarfare macrumors G3


    Nov 26, 2007
    Just curious - why would you want to use assembly? The only time I've ever used the asm function in Xcode in X was when I wanted to access the built in random number generator on Intel's recent chips. That was really just to overkill a basic school assignment.
  6. Elhardt thread starter macrumors newbie

    Sep 21, 2013
    Thanks for the link, but I've already been there and seen that stuff. They explain the commands the assembler uses, the syntax the assembler uses, and stuff like that. I know that already. I can currently write an assembly program and assemble it in NASM from the terminal and create object files or executable files. But what I need is something that tells me how to use my assembly code from within C, like how to link in the assembler code, pass variables between C and assembly, and how to do all that from the Xcode IDE.

    I tried searching for assembler and found some info about building, loading, executing Mach-O files, which seems like it's somewhat related in some way, though I'm still not seeing a step by step guide on how to accomplish combined C and assembly language programming in Xcode.
  7. Elhardt thread starter macrumors newbie

    Sep 21, 2013
    I use assembly code because I need the tightest fastest code possible. I need to use the vector capabilities of SSE and AVX. I need to be able to have control over arranging code and register usage. And some algorithms I've written use processor features like the carry flag, multiple status registers, counting leading zeros, rotate instructions, and so forth, that C has no access to. And I was a commercial programmer a while back too with my code even getting into a big arcade game console, so it's important for my code to be top notch and top speed for realtime applications, as opposed to something for a school project.
  8. subsonix macrumors 68040

    Feb 2, 2008
    Have you considered the Accelerate framework? That way you can avoid optimizing for specific CPUs, and get the benefits accross all Apple hardware. Very few people write faster assembly than what the compiler will generate, especially with optimizations turned on.
  9. ArtOfWarfare macrumors G3


    Nov 26, 2007
    In addition to Subsonix's points, it seems to me that any speed gains you'll get will come at fairly high cost in your time programming it the first time, and then reading and debugging it again later.
  10. ghellquist macrumors regular

    Aug 21, 2011
    Stockholm Sweden
    Does this work?

    __asm__ {
    int 3;
    mov eax, [x+4] ;
    movss xmm1,[f+4] ;
    fld [fa+4] ;
    Write it inside a Objective c function in order to get all registers and other environment setup.
  11. Elhardt thread starter macrumors newbie

    Sep 21, 2013
    Sometimes these threads get kind of ridiculous. I came to ask a question and then get a bunch of people second guessing me, despite the fact that I've been programming assembly for 32 years and can do it better than just about anybody, have explained why it's faster (and in some cases a lot faster) than C or any high level language, that there are things that can be done in assembly that can't in C, and that maximum no compromise speed is what I'm after. Yet all that's ignored and I'm given the same old canned statement from people who don't understand CPU architecture, that some high level language or "framework" is probably faster than what I can program, as if I'm incompetent and computer illiterate.

    High level languages will never be as fast as assembly. And I'm disturbed by the inefficiencies and waste I constantly see in assembly dumps from compilers. And since my code is already written in assembler on the PC and needs to be cross platform, using anything Apple specific is out, and converting assembly to slower C would be a major effort for slower speed, as opposed to a simple copy and paste, and then some conversion from SSE to AVX.

    So it's back the problem at hand. I've done C combined with assembly code for years in Consulair C, Think C, Apple's MPW, CodeWarrior, Microsoft Visual C, Pelles C, and FreeBasic. Now I get to Xcode of which Apple includes the NASM assembler, but they don't bother to give a single example of how to use NASM with Xcode. All I want is the few steps to get that done and get over the hump.


    See my above comment to Subsonix.

    And the code is already written on the PC. it's the job of a programmer to spend time writing quality code. Unfortunately, mediocrity seems to be what programmers are all about these days and they want to drag me down to that level too.
  12. Elhardt thread starter macrumors newbie

    Sep 21, 2013
    I've seen posts in other forums where people were recommending similar things and it got my hopes up. I'm not sure what is considered an Objective-C function as I'm new to Xcode and write in C. I can set my source file type to Objective C and write a normal C function, but when I try your way of doing things Xcode reports that it doesn't like MS style assembly and fails to compile or it says "(" is expected after "asm" meaning it's trying to lead me down the awful ATT/GCC way of doing things. What you have there is exactly the way I'd like to do it, I just need to find out whether it's possible to enter clean Intel syntax code like your example shows, and if so, the steps that need to be taken to set Xcode up to accept it.

    If that won't work, then I need instructions on using NASM with Xcode.

  13. MeUnix macrumors 6502

    Aug 21, 2013
    San Francisco
    Although my answer to your question isn't any different then what other members said ( asm(); ), how can you expect someone to help you when you go on a rant, then put down other programmers by saying we all do mediocre work compared to yours? We're offering help, sorry it's not solving YOUR problem. Maybe if you weren't so narcissistic about your coding skills someone who has your answer will chime in.

    BTW, like another member said, Apple did away with assembly compiler and replaced it with LLVM
  14. subsonix, Sep 22, 2013
    Last edited: Sep 22, 2013

    subsonix macrumors 68040

    Feb 2, 2008
    Your answer is ridiculous, I didn't second guessed you, or question your intentions and now you are the one who make assumptions. I specifically added a question related to the use of SIMD instructions, apart from Apple's Accelerate framework intel also have intrinsics to do the same So it's more of a side note, that may be useful. I, like you have no idea how this is achieved in Xcode (using intel syntax, not AT&T), I have used NASM, but never with Xcode, see? Usually by having the assembly file in a separate .s file that is assembled separately then linked with ld to a Mach-O file.
  15. ghellquist macrumors regular

    Aug 21, 2011
    Stockholm Sweden
    Hi Elhardt.
    Sorry, but I was wrong and you was right. Xcode by default uses the LLVM compiler and that definitely has its own syntax.

    But if you want to simply combine C and asm there really is no need to use the xcode Environment. Xcode shines when you want to do GUI things on top of Cocoa, with all its widgets and stuff. Then there is an interface designer and so on.

    There is of course the standard setup of c compiler, assembler, linker, make, lib and so on available on the mac. It is a reasonably simple to setup i c program and link it to create a command line program. And this can be run in the terminal. This works very much the same in *nix and windows, inside the Mac OSX there is a *nix variant. The link below might be a starting Point although it is not totally up to date.

    It is possible to combine an objective C GUI frontend in your application with a C / asm backend as xcode can link in various stuff.

    And the long debate of why you wish to code in assembly is best left out here. It is like asking a person why he wants to climb the Mount Everest, where the best answer is "because it is there". So go for it!

    // Gunnar
  16. subsonix macrumors 68040

    Feb 2, 2008
    You can use fasm code blocks like you showed earlier in Xcode if you set the compiler to llvm-gcc in build settings. I had no problem to get that to work. Alternatively using gcc separately with the -fasm-blocks flag.
  17. xStep macrumors 68000

    Jan 28, 2003
    Less lost in L.A.
    Elhardt mentioned he'd seen other recommend setting up some flags but he/she doesn't know Xcode well enough to know where to place them. Can you shine some light on that as it may help.
  18. subsonix macrumors 68040

    Feb 2, 2008
    The flag is just a command line option if you are using gcc by it self, and therefor llvm-gcc. FWIW, Clang also supports inline assembly with intel syntax, haven't looked into that though. For Xcode, set the compiler to llvm-gcc in build settings as I mentioned, 5 minutes on Google should be enough.
  19. firewood macrumors 604

    Jul 29, 2003
    Silicon Valley
    Do not assume someone asking such a question is not one of those. I knew people who wrote those compiler optimizations. Some they left out to meet schedule.

    Do not assume that the profits to be made don't vastly overweigh the time taken to properly optimize an app. Some people on these forums have been involved in multi-million dollar supercomputer bids (or other high volume applications) where the consulting fees for a whole year of your dev time would make up a fraction of the possible profit from a winning (beats the competition) bid.

    So back to the question: Can anyone point to a working example of using asm (arm and x86) in an Xcode/clang/llvm compiled app?
  20. subsonix macrumors 68040

    Feb 2, 2008
    Did I? What I said is generally true. I tried to find a Sun blog about this subject (with examples of trying to beat a compiler at -O3 optimizations) unfortunately Oracle have removed it. But I can post some code and you or him can add his assembly then we'll see.

    Set the compiler to llvm-gcc, it will compile fasm-blocks as posted here earlier. Since llvm is used for more than compiling such as code completion, changing the front end to gcc will mean that the suggestion that you get from Xcode 4 is not correct so turn that off. It will compile, did you try it? Of course you didn't.
  21. Elhardt thread starter macrumors newbie

    Sep 21, 2013
    Sorry for the delay at getting back to this thread as I got pulled away and busy with other things.

    My rant wasn't to people trying to help. It was to those who don't help but instead question why I, or anybody would use assembly, and then claim it's not needed. Then I have to point out the error in their thinking as I know full well where it's needed and the kind of speed gains achievable. I see too many posts on all kinds of forums where people ask if assembly code is needed or not. But they never consider, needed FOR WHAT? High level languages are for high level things, like business apps, or the main logic for a game. But when it comes to the repetitive computations that are running millions of times a second, that's where assembly is needed for full speed. I could post lots of specific examples in code I've written showing the speed increases using assembly code, but it's not really relevant to the topic at hand. People often mention SSE intrinsics. That's basically a way of using SSE assembly code from C. So there you go. People programming in SSE assembly code yet claiming it's not necessary. However, there's more to assembly code than just the SSE vector unit. It's all the rest of x86 code too, or PowerPC, ARM, 68K, etc. And even with SSE intrinsics, you have no control over register usage from C and get watered down code.

    If you're talking about the example ghellquist gave with the __asm__ { bit, I can't get xcode to recognize anything like that. That was the problem. Xcode complains about any inline assembly that's not done in that awful ATT manner that wants every assembly instruction in a printf-like function. The compiler chosen is llvm-gcc as that's all Apple supplies anymore. ghellquist mentioned something about Objective C. I'll have to check into that. The link you provided for Clang only shows ATT style assembly.

    You also mention doing things from the command externally to Xcode. That might be my only option if Xcode is so incapable of doing all of the compiling, assembling and linking for me. Can't believe in the year 2013, Xcode can't do what I've been doing for years/decades on older computers.

    -Elhardt (I'm a he, not a she)
  22. Elhardt thread starter macrumors newbie

    Sep 21, 2013
    Well I finally achieved a bit of success. I went back and tried ghellquist's __asm__ example in inline assembly again, but this time I started a C++ project instead of C, and I changed the compiler from LLVM 4.2 to LLVM GCC 4.2. I thought there was only one compiler option, but my mistake, as they look almost the same. I don't know what one of those changes worked, but the Xcode editor stopped complaining about the inline asm syntax, compiled it, and ran it okay.

    So I finally thought I'm over the hump and then find that it doesn't recognize AVX instructions. Build options only list up to SSE4.2 that can be enabled. So the fight continues. I'm sure Xcode can work in conjunction with external assembler NASM because I found entries for NASM in Build Rules, plus NASM Identity type and editor syntax coloring. I'm going to have to investigate those Build Rules and see if I can figure out how to use them.

  23. gnasher729, Oct 3, 2013
    Last edited: Oct 3, 2013

    gnasher729 macrumors P6


    Nov 25, 2005
    Vector operations are all available directly. Look at the LLVM documentation, search for "vector extensions", and you can directly declare SIMD vectors as C datatypes and use them, plus all the functionality is there as inline functions if you just include the right header files. Leading zeroes count, carry flags and so on are all there as well. No need for any assembler code.

    And in my experience, when I want to make code fast, it's an iterative process where you start understanding the problem properly and improve your algorithms accordingly, and using hard-to-maintain assembler code usually gets in the way.

    Today, assembler code is quite pointless. The most important things are: 1. Multi-threading. 2. Caching. 3. Avoiding latency. None of these can be done using assembler.

    gcc 4.2 is deprecated and many years old. LLVM 4.2 supports AVX with no problems. Just pick the right compiler option.
  24. gnasher729, Oct 3, 2013
    Last edited: Oct 3, 2013

    gnasher729 macrumors P6


    Nov 25, 2005
    Some C++ code to get the 128 bit product of two 64 bit numbers:

    static inline void mult128 (uint64_t& prod_hi, uint64_t& prod_lo, uint64_t x, uint64_t y) {
    	__asm__ ( "mulq %2"			// rdx:rax = Operand 2 * rax
    			: "=d" (prod_hi),	// 64 high bits returned in rdx
    			  "=a" (prod_lo)	// 64 low bits returned in rax
    			: "%rm" (x),		// Input x can be in register or memory, operands can be swapped
    			  "a" (y)		// Input y must be in rax

    Well, I've written COMPASS code in 1979 or 1980...

    You need the gcc compiler documentation and dig your way through the inline assembler portion (horrible to read, but it works and applies to LLVM as well), the LLVM documentation for all the inlined functions, get the latest LLVM and go through the compiler options, and then:

    1. Learn about Grand Central Dispatch
    2. Learn about the Accelerate Framework
    3. Learn about OpenCL (their sample code did 50 GFlops on my 2006 MacBook)
    4. Learn how caches work
    5. Learn how to get around latency limits.

    Things that were true 32 years ago are not necessarily true today. And things that were important 32 years ago are not necessarily important today.

Share This Page