我在C:中有这个函数
int write(int fd, char *buffer, int size)
{
int ret;
__asm__("mov $4, %%eax;"
"mov %0, %%ebx;"
"mov %1, %%ecx;"
"mov %2, %%edx;"
"int $0x80"
: "=r"(ret)
: "g"(fd), "g"(buffer), "g"(size)
: "eax", "ebx", "ecx", "edx");
if (ret < 0) {
return -1;
} else {
return 0;
}
}
这在 ASM 中翻译成这段代码:
push %ebp
mov %esp,%ebp
push %esi
push %ebx
mov $0x4,%eax
mov %esi,%ebx
mov 0x8(%ebp),%ecx
mov 0xc(%ebp),%edx
int $0x80
mov %esi,%eax
sar $0x1f,%eax
pop %ebx
pop %esi
pop %ebp
ret
由于fd、*buffer和size是函数参数,它们分别位于0x8(%ebp)、0xc(%ebp)和0x10(%ebp)中。为什么GCC会识别fd在%esi中的位置,而其他两个变量在堆栈中移动?我怎样才能运行这个函数(正确获取寄存器中的变量)?
最佳答案
这可能是您的架构上的调用约定。如果您想将其他参数约束到寄存器,您应该直接使用寄存器约束:例如。 “a”
代表eax
寄存器。
而且开头的 $4
在我看来也是错误的。
一些事情
__asm__(
"int $0x80"
: "=b"(ret)
: "c"(fd), "d"(buffer), "a"(size)
);
如果这些确实是您的系统调用使用的寄存器,则应该这样做。
但是,总的来说,我认为你不应该自己这样做。您的操作系统肯定有类似 syscall
之类的东西,可以为您提供该功能。
关于c - C 中的内联汇编。错误的翻译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25951065/