Как написать многострочный встроенный код ассемблера в GCC C ++? - PullRequest
8 голосов
/ 08 сентября 2010

Это выглядит не слишком дружелюбно:

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

Неужели мне действительно нужно ставить двойные кавычки вокруг каждой строки?

Также ... так как многострочные строковые литералы не работают в GCC, я не мог обмануть и это.

Ответы [ 2 ]

10 голосов
/ 08 сентября 2010

Я всегда нахожу в Интернете некоторые примеры, когда парень вручную вставляет табуляцию и новую строку вместо \ t и \ n, однако у меня это не работает.Не совсем уверен, что ваш пример даже компилируется ... но я так делаю:

ОЧЕНЬ безобразный способ:

asm("xor %eax,%eax");
asm("mov $0x7c802446, %ebx");
asm("mov $500, %ax");
asm("push %eax");
asm("call *%ebx");

Или этот менее уродливый:

asm("xor %eax,%eax         \t\n\
    mov $0x7c802446, %ebx  \t\n\
    mov $1000, %ax         \t\n\
    push %eax              \t\n\
    call *%ebx             \t\n\
    ");
2 голосов

C ++ многострочные строковые литералы

Интересно, как этот вопрос указал мне на ответ:

main.cpp

#include <cassert>
#include <cinttypes>

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

Скомпилируйте и запустите:

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

См. Также: Многострочный строковый литерал C ++

GCC также добавляет тот же синтаксис, что и расширение C, вам просто нужно использовать -std=gnu99 вместо-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);
}

Скомпилировать и запустить:

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

См. Также: Как разбить строковый литерал на несколько строкв C / Objective-C?

Недостатком этого метода является то, что я не вижу, как добавить макросы препроцессора C в сборку, поскольку они не раскрываются внутри строк, см. также: Многострочный встроенный макрос сборки со строками

Протестировано в Ubuntu 16.04, GCC 6.4.0, binutils 2.26.1.

.incbin

Эта директива GNU GAS - это еще одна вещь, которая должна быть в вашем радаре, если вы собираетесь использовать большие блоки сборки: Встраивание ресурсов в executable с помощью GCC

Сборка будет в отдельном файле, поэтому это не прямой ответ, но об этом все же стоит знать.

...