内联汇编 - AT& T语法 - 如何移动到变量

时间:2011-12-05 23:44:24

标签: macos assembly inline-assembly att

所以我正在编写一个代码洞,我基本上用跳转替换了对_memcpy的调用,然后我想保存源代码中的内容。原装配:

mov     [esp+8], edx    ; size
mov     [esp+4], eax    ; ptr to source
mov     eax, [ebp+arg_4]
mov     [esp], eax      ; ptr to destination
call    _memcpy

我正在为AT& T的语法挣扎,基本上我想在我自己的变量中存储[esp + 8],[esp + 4]和[esp]。我试着这样做:

void codecave_jump( void ) __attribute__ ( ( signal, naked ) );
void codecave_jump( void ){

    void *destination, *source;
    size_t size;

    // push all registers onto the stack
    __asm__("pushal\n\t");

    // get size
     __asm__ __volatile__(
            "movl 8(%ecx), %0\n\t" : "=g" (size)
            );

    // get source
    __asm__ __volatile__(
            "movl 4(%ecx), %0\n\t" : "=g" (source)
            );

    // get destination
    __asm__ __volatile__(
            "movl %%eax, %0\n\t" : "=g" (destination)
            );

    // restore all of our registers
    __asm__("popal\n\t");

    // call memcpy
    __asm__("call __memcpy\n\t");

    // do the copy
    memcpy(destination, source, size);
}

我收到以下错误: 错误:%-letter后缺少操作数 错误:%-letter

后缺少操作数

基本上它对我大吼大叫: “movl 8(%ecx),%0 \ n \ t”:“= g”(大小)

有谁知道我应该如何在AT& T语法中正确地做到这一点?我真的很想念OS X上的Intel语法:/

1 个答案:

答案 0 :(得分:1)

由于生成的AT& T代码使用百分号作为寄存器名称,因此当存在诸如size之类的操作数时,您必须use double percent signs作为寄存器名称:

"movl 8(%%ecx), %0\n\t" : "=g" (size)

这与你有时需要printf的双百分号相似。 似乎你在%%eax进一步向下,我猜这条线编译得很好。


mov mem32, mem32没有操作码。您首先需要将数据移动到寄存器,然后将其移动到内存位置(就像英特尔版本对destination所做的那样)

// get size
__asm__ __volatile__(
    "movl 8(%ecx), %eax\n\t"
    );
__asm__ __volatile__(
    "movl %%eax, %0\n\t" : "=g" (size)
    );

为了记录:我还发现AT& T语法令人难以置信的混乱。 :)