Это мой способ определения функции в сборке, для этого не нужно иметь отдельный файл на ассемблере, и вам не нужно экранировать каждую новую строку. Вы можете просто скопировать содержимое файлов сборки в строковый литерал. Примечание: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * C ++ 11 * (Вы также пометили C ++). Это полезно, если вы хотите скомпилировать все в один .c
- / .cpp
-файл.
extern"C" int rand_byte(void);
asm (R"(
.globl rand_byte
rand_byte:
call rand
and eax, 255
ret
)");
Вы можете использовать только базовую инструкцию сборки без дополнительных параметров в глобальной области видимости.
При использовании GCC или Clang и процессора руки вы можете использовать [[gnu::naked]]
/ __attribute__((naked))
.
[[gnu::naked]]
int rand_byte(void) {
asm volatile (R"(
push {lr}
bl rand
and r0, #255
pop {pc}
)");
};
Первый способ всегда позволяет определять голые функции.
Это также помогает создавать более переносимый код.
extern"C" int _cdecl rand_byte(void);
#if defined __x86__
// NOTE: the names are decorated with a '_' on windows 32-bit
// You can use extern"C" int _cdecl rand_byte() asm("rand_byte");
// to make the asm symbol name always be rand_byte, without an _
asm volatile (R"(
.globl _rand_byte
_rand_byte:
call rand
and eax, 255
ret
)");
#elif defined __x86_64__
asm volatile (R"(
.globl rand_byte
rand_byte:
call rand
and rax, 255 # eax works here, too. x86-32 and -64 could share the same source.
ret
)");
#elif defined __arm__
asm (R"(
.global rand_byte
rand_byte:
push {lr}
bl rand
and r0, #255
pop {pc}
)");
#else
#error There is no code for your platform yet...
#endif