gpt4 book ai didi

c - 我如何在汇编中编写所有这些

转载 作者:IT王子 更新时间:2023-10-29 00:20:58 26 4
gpt4 key购买 nike

我有两个宏,一个是用汇编写的,另一个是用C写的。第二个宏使用了第一个宏。但是,我还想用 volatile 在汇编中编写第二个宏,这样我就可以控制它在代码中的位置。请注意,tid 是一个运行时值,而不是像 n 这样的常量。

用汇编编写它的好方法是什么?此外,是否可以控制 C 代码的放置,例如使用 volatile 的汇编?

#define SAVE_SP(n) __asm__ __volatile__ ("movq %rsp, msp"#n";" \
"movq ts"#n", %rsp;" \
)

#define SAVE_STACK_POINTER( tid ) \
switch( tid ) \
{ \
case 0: \
SAVE_SP( 0 ); \
break; \
case 1: \
SAVE_SP( 1 ); \
break; \
case 2: \
SAVE_SP( 2 ); \
break; \
case 3: \
SAVE_SP( 3 ); \
break; \
}

最佳答案

您可以询问 gcc 如何用汇编编写代码:gcc -S foo.cgcc -Wa,-alh=foo.s -c foo.c 。当然,您可能希望改进结果。您将需要做一些额外的事情:使用 %0 作为您为程序集 block 传递的参数,并声明您已破坏的寄存器。查找Assembler Instructions with C Expression Operands in the GCC manual如果你不熟悉。这看起来可能是这样的(警告,直接在浏览器中输入,并不真正了解 x86 汇编语法)。

#define SAVE_STACK_POINTER(tid) __asm__ __volatile__ (" \
cmpl $0, %0 \n\
je .SAVE_STACK_POINTER_0 \n\
cmpl $1, %0 \n\
je .SAVE_STACK_POINTER_1 \n\
cmpl $2, %0 \n\
je .SAVE_STACK_POINTER_2 \n\
cmpl $3, %0 \n\
je .SAVE_STACK_POINTER_3 \n\
jmp .SAVE_STACK_POINTER_done \n\
.SAVE_STACK_POINTER_0: \n\
movq %%rsp, msp0 \n\
movq ts0, %%rsp \n\
jmp SAVE_STACK_POINTER_done \n\
.SAVE_STACK_POINTER_1: \n\
movq %%rsp, msp1 \n\
movq ts1, %%rsp \n\
jmp SAVE_STACK_POINTER_done \n\
.SAVE_STACK_POINTER_2: \n\
movq %%rsp, msp2 \n\
movq ts2, %%rsp \n\
jmp SAVE_STACK_POINTER_done \n\
.SAVE_STACK_POINTER_3: \n\
movq %%rsp, msp3 \n\
movq ts3, %%rsp \n\
.SAVE_STACK_POINTER_done: \n\
" : : "r" (tid))

更高级的方法是计算每个 movq-movq-jmp block 占用多少字节(注意:我还没有检查过,我使用 8) 并计算跳入其中;像

__asm__("                        \n\
movl %0, %eax \n\
mul 8, %eax \n\
add 4, %eax \n\
jmp . + %eax \n\
movq %%rsp, msp0 \n\
movq ts0, %%rsp \n\
jmp .SAVE_STACK_POINTER_done \n\

.SAVE_STACK_POINTER_done: \n\
" : : "r" (tid) : "%eax")

关于c - 我如何在汇编中编写所有这些,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8271899/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com