12

This does not look too friendly:

__asm("command 1"
      "command 2"
      "command 3");

Do I really have to put a doublequote around every line?

Also... since multiline string literals do not work in GCC, I could not cheat with that either.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
johnny-john
  • 846
  • 2
  • 9
  • 19
  • [Can I write multiple Assembly instructions on the same line?](https://stackoverflow.com/q/27685548/995714) – phuclv Feb 07 '19 at 15:00

2 Answers2

18

I always find some examples on Internet that the guy manually insert a tab and new-line instead of \t and \n, however it doesn't work for me. Not very sure if your example even compile.. but this is how I do:

asm volatile(           // note the backslash line-continuation
   "xor %eax,%eax          \n\t\
    mov $0x7c802446, %ebx  \n\t\
    mov $1000, %ax         \n\t\
    push %eax              \n\t\
    call *%ebx             \n\t\
    add $4, %esp           \n\t\
    "
    : "=a"(retval)        // output in EAX: function return value
    :
    : "ecx", "edx", "ebx"   // tell compiler about clobbers
  // Also x87 and XMM regs should be listed.
 );

Or put double quotes around each line, instead of using \ line-continuation. C string literals separately only by whitespace (including a newline) are concatenated into one long string literal. (Which is why you need the \n inside it, so it's separate lines when it's seen by the assembler).

This is less ugly and makes it possible to put C comments on each line.

asm volatile(
    "xor %eax,%eax          \n\t"
    "mov $0x7c802446, %ebx  \n\t"
    "mov $1000, %ax         \n\t"
    "push %eax              \n\t"  // function arg
    "call *%ebx             \n\t"
    "add $4, %esp           \n\t"  // rebalance the stack: necessary for asm statements
  : "=a"(retval)
  :
  : "ecx", "edx", "ebx"    // clobbers.  Function calls themselves kill EAX,ECX,EDX
  // function calls also clobber all x87 and all XMM registers, omitted here
);
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
jyz
  • 6,011
  • 3
  • 29
  • 37
  • Thanks mate, that's more or less what I have seen in examples, however, it is still just "less ugly" for sure! Takes my motivation away from writing asm. – johnny-john Sep 08 '10 at 15:54
  • So less-but-still-ugly! Thanks! :) – bigjosh Nov 29 '18 at 00:27
  • 5
    The alternative to `\t\n` is semicolon to separate instructions. `\t\n` is better because the resulting asm output won't be a mess. It's typical to use `"insn \n\t"` `"insn2 \n\t"` etc, and let string concatenation work, though, instead of ending each line with a backslash. – Peter Cordes Feb 06 '19 at 23:21
  • 1
    The very ugly way is also the will-unexpectedly-not-work way, though the less ugly way also suffers from this problem. – Ross Ridge Feb 08 '19 at 23:49
6

C++ multiline string literals

Interesting how this question pointed me to the answer:

main.cpp

#include <cassert>
#include <cinttypes>

int main() {
    uint64_t io = 0;
    __asm__ (
        R"(
incq %0
incq %0
)"
        : "+m" (io)
        :
        :
    );
    assert(io == 2);
}

Compile and run:

g++ -o main -pedantic -std=c++11 -Wall -Wextra main.cpp
./main

See also: C++ multiline string literal

GCC also adds the same syntax as a C extension, you just have to use -std=gnu99 instead of -std=c99:

main.c

#include <assert.h>
#include <inttypes.h>

int main(void) {
    uint64_t io = 0;
    __asm__ (
        R"(
incq %0
incq %0
)"
        : "+m" (io)
        :
        :
    );
    assert(io == 2);
}

Compile and run:

gcc -o main -pedantic -std=gnu99 -Wall -Wextra main.c
./main

See also: How to split a string literal across multiple lines in C / Objective-C?

One downside of this method is that I don't see how to add C preprocessor macros in the assembly, since they are not expanded inside of strings, see also: Multi line inline assembly macro with strings

Tested on Ubuntu 16.04, GCC 6.4.0, binutils 2.26.1.

.incbin

This GNU GAS directive is another thing that should be in your radar if you are going to use large chunks of assembly: Embedding resources in executable using GCC

The assembly will be in a separate file, so it is not a direct answer, but it is still worth knowing about.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985