内联汇编 - 无用的中间复制指令
inline assembly - useless intermediate copy instructions
我正在尝试为 运行 我们所说的 "fibers" 编写调度程序。
不幸的是,我不太习惯编写内联汇编。
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 , %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
s 编译成临时寄存器?我能以某种方式摆脱它们吗?
这个问题的第一个版本有来自 gcc -O0
的 asm 输出,有更多的指令和临时变量。
打开优化并不能消除它们。
turning them on does not get rid of the temporaries
它确实摆脱了一些额外的加载和存储。 fib
当然仍然存在于内存中,因为您将其声明为全局变量。 rax
是 malloc
中的 return 值,必须分配给内存中的 fib
。另外两行写入您的 fib
成员,这也是必需的。
由于您指定了寄存器输出,因此 asm 块无法直接写入内存。不过,这很容易通过内存限制来解决:
__asm__(
"movq %%rsp, %0;"
"movq %%rbp, %1;"
: "=m"(fib->rsp),"=m"(fib->rbp)
);
这将生成:
call malloc
movq %rax, fib(%rip)
movq %rsp, (%rax)
movq %rbp, 8(%rax)
我正在尝试为 运行 我们所说的 "fibers" 编写调度程序。 不幸的是,我不太习惯编写内联汇编。
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 , %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
s 编译成临时寄存器?我能以某种方式摆脱它们吗?
这个问题的第一个版本有来自 gcc -O0
的 asm 输出,有更多的指令和临时变量。
打开优化并不能消除它们。
turning them on does not get rid of the temporaries
它确实摆脱了一些额外的加载和存储。 fib
当然仍然存在于内存中,因为您将其声明为全局变量。 rax
是 malloc
中的 return 值,必须分配给内存中的 fib
。另外两行写入您的 fib
成员,这也是必需的。
由于您指定了寄存器输出,因此 asm 块无法直接写入内存。不过,这很容易通过内存限制来解决:
__asm__(
"movq %%rsp, %0;"
"movq %%rbp, %1;"
: "=m"(fib->rsp),"=m"(fib->rbp)
);
这将生成:
call malloc
movq %rax, fib(%rip)
movq %rsp, (%rax)
movq %rbp, 8(%rax)