如何在汇编中编写所有这些内容

Met*_*est 8 c linux x86 assembly gcc

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

在汇编中写这个的好方法是什么?另外,是否可以通过volatile来控制C代码的放置?

#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; \
    }
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 6

您可以向gcc询问如何在汇编中编写代码:gcc -S foo.c或者gcc -Wa,-alh=foo.s -c foo.c.当然,您可能希望改进结果.您需要做一些额外的工作:使用%0您为程序集块传递的参数,并声明您已经破坏的寄存器.如果您不熟悉,请在GCC手册中查找带有C表达式操作数的汇编程序指令.这可能是这样的(警告,直接输入到浏览器中,并不真正了解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))
Run Code Online (Sandbox Code Playgroud)

票友方法会涉及搞清楚每个多少字节movq- movq- jmp块需要(注:我没有检查,我使用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")
Run Code Online (Sandbox Code Playgroud)