===更新===
截至 2023 年,它们确实有效:
__attribute__((naked))
void my_write(int fd, char const* str, int size) {
asm
(
" pusha \n\t"
" movl $4, %eax \n\t"
" movl 36(%esp), %ebx \n\t"
" movl 40(%esp), %ecx \n\t"
" movl 44(%esp), %edx \n\t"
" int $0x80 \n\t"
" popa \n\t"
" ret \n\t"
);
}
void _start() {
my_write(1, "hi\n", 3);
my_write(1, "bye\n", 4);
}
Run Code Online (Sandbox Code Playgroud)
编译gcc -m32 -nostdlib my_write.c
使用gcc version 10.2.1 20210110 (Debian 10.2.1-6)
===旧答案===
在 x86 上,您可以通过在全局范围内使用 asm 来解决:
void my_write(int fd, const void *buf, int count);
asm
(
".global my_write \n\t"
"my_write: \n\t"
" pusha \n\t"
" movl $4, %eax \n\t"
" movl 36(%esp), %ebx \n\t"
" movl 40(%esp), %ecx \n\t"
" movl 44(%esp), %edx \n\t"
" int $0x80 \n\t"
" popa \n\t"
" ret \n\t"
);
void _start()
{
my_write(1, "hi\n", 3);
my_write(1, "bye\n", 4);
}
Run Code Online (Sandbox Code Playgroud)
也naked
列在x86 函数属性中,所以我认为它适用于较新的 gcc。
根据文档,仅 GCC 在某些平台(ARM、AVR、MCORE、RX 和 SPU)上支持裸属性:
naked
: 在ARM、AVR、MCORE、RX 和SPU 端口上使用该属性来表示指定的函数不需要编译器生成的序言/尾声序列。由程序员提供这些序列。唯一可以安全地包含在裸函数中的语句是没有操作数的 asm 语句。应避免使用所有其他语句,包括局部变量的声明、if 语句等。裸函数应该用于实现汇编函数的主体,同时允许编译器为汇编器构造必要的函数声明。
我不知道为什么。