Asm代码的说明

jam*_*o00 6 x86 assembly lua gcc inline-assembly

以下GCC内联asm取自LuaJit的coco库.有人可以逐行解释它的作用吗?

static inline void coco_switch(coco_ctx from, coco_ctx to)
{
  __asm__ __volatile__ (
    "movl $1f, (%0)\n\t" 
    "movl %%esp, 4(%0)\n\t" 
    "movl %%ebp, 8(%0)\n\t"
    "movl 8(%1), %%ebp\n\t" 
    "movl 4(%1), %%esp\n\t" 
    "jmp *(%1)\n" "1:\n"
    : "+S" (from), "+D" (to) : : "eax", "ebx", "ecx", "edx", "memory", "cc");
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Dev*_*lar 10

我的ASM对细节有点模糊,但我想我可以给你一个大概的想法.

ESP:堆栈指针,EBP:基指针.

movl $1f, (%0)
Run Code Online (Sandbox Code Playgroud)

将值0x1f移动到参数0(从).

movl %%esp, 4(%0)
Run Code Online (Sandbox Code Playgroud)

将寄存器ESP的内容移动到(从+ 4开始).

movl %%ebp, 8(%0)
Run Code Online (Sandbox Code Playgroud)

将寄存器EBP的内容移入(从+ 8开始).

movl 8(%1), %%ebp
Run Code Online (Sandbox Code Playgroud)

将(到+ 8)的内容移动到寄存器EBP中.

movl 4(%1), %%esp
Run Code Online (Sandbox Code Playgroud)

将(到+ 4)的内容移动到寄存器ESP中.

jmp *(%1)
Run Code Online (Sandbox Code Playgroud)

跳转到(to)中包含的地址.

"1:"是跳转标签.

"+ S"声明"源"(读)参数,"+ D"表示目标(写入)参数.语句末尾的寄存器列表是"clobber"列表,可能由ASM代码修改的寄存器列表,因此编译器可以采取措施来保持一致性(即,不依赖于例如ECX仍然包含相同的值像之前一样).

我猜coco_ctx的意思是"coco context".因此:该函数将当前堆栈帧保存在"from"结构中,并将堆栈帧设置为"to"结构中保存的内容.基本上,它从当前函数跳转到另一个函数.

  • 这是完全正确的.不过,它不仅仅是从一个函数跳转到另一个函数:它从一个完整的调用堆栈跳转到另一个函数; 它完全切换执行上下文.(另外,gosh但是GCC内联汇编语法很奇怪.) (2认同)
  • 它的AT&T语法(http://wiki.osdev.org/Opcode_syntax)包含在C函数调用语法中(http://wiki.osdev.org/Inline_Assembly).你不会相信它,但我实际上更喜欢它而不是"标准"英特尔语法.;-) (2认同)
  • 我认为第一行可能是错误的。$1f 可能是“向前”方向上名为“1”的下一个标签的地址(请参阅http://stackoverflow.com/questions/3898435/labels-in-gcc-inline- assembly)。 (2认同)