我试图编写一个调度程序来运行我们称之为" fiber"。 不幸的是,我并不习惯于编写内联汇编。
typedef struct {
//fiber's stack
long rsp;
long rbp;
//next fiber in ready list
struct fiber *next;
} fiber;
//currently executing fiber
fiber *fib;
因此,第一项任务是 - 显然 - 为main
函数创建一条光纤,以便它可以被暂停。
int main(int argc, char* argv[]){
//create fiber for main function
fib = malloc(sizeof(*fib));
__asm__(
"movq %%rsp, %0;"
"movq %%rbp, %1;"
: "=r"(fib->rsp),"=r"(fib->rbp)
);
//jump to actual main and execute
__asm__(...);
}
这会被编译为
movl $24, %edi #,
call malloc #
#APP
# 27 "scheduler.c" 1
movq %rsp, %rcx;movq %rbp, %rdx; # tmp92, tmp93
# 0 "" 2
#NO_APP
movq %rax, fib(%rip) # tmp91, fib
movq %rcx, (%rax) # tmp92, MEM[(struct fiber *)_3].rsp
movq %rdx, 8(%rax) # tmp93, MEM[(struct fiber *)_3].rbp
为什么将mov
编译成临时寄存器?我可以以某种方式摆脱它们吗?
这个问题的第一个版本有gcc -O0
的asm输出,有更多的指示和临时值。
启用优化并没有摆脱它们。
答案 0 :(得分:3)
打开它们并没有摆脱临时工作
它确实摆脱了一些额外的装载和存储。 fib
当然仍然存在于内存中,因为您将其声明为全局变量。 rax
是必须分配给内存中malloc
的{{1}}的返回值。其他两行写入您的fib
成员,这也是必需的。
由于您指定了寄存器输出,因此asm块无法直接写入内存。但是,通过内存约束很容易解决:
fib
这将产生:
__asm__(
"movq %%rsp, %0;"
"movq %%rbp, %1;"
: "=m"(fib->rsp),"=m"(fib->rbp)
);