如何从程序集更改指针值(x86)

时间:2014-03-09 04:45:26

标签: c assembly x86

这是我的C代码,用于更改指针值

     #include<stdio.h>
     #include<stdlib.h>
     typedef struct tcb tcb_t;

     struct tcb { 
     void* sp; 
     int id;        
     };


    void* changePointer(struct tcb*);
    int main(){
         struct tcb* s;
         s=malloc(sizeof(struct tcb*));
        printf("%p\n",changePointer(s));
        printf("%p\n",s);
   return 0;
  }

这是我的汇编函数(x86)

    .text
    .globl changePointer

   changePointer:
   push %ebp
   movl %esp, %ebp      
   movl 0x8(%ebp),%eax//original pointer value
   movl %ebp,%esp
   movl %ebp,0x8(%ebp) //it is to be the value  after changing
   popl %ebp
   ret

但它没有改变汇编函数内的指针值。请解释哪里出错了?

3 个答案:

答案 0 :(得分:0)

您的函数“changePointer”未设置其返回值(在寄存器eax中)。

它不称为“汇编”,它被称为“汇编程序”!

答案 1 :(得分:0)

movl %ebp,%esp

无论你想用这条线做什么:它不会这样做!此时EBP和ESP具有相同的值,因此该行根本不执行任何操作(否则会更改堆栈指针会导致程序崩溃)!

movl %ebp,0x8(%ebp)

0x8(%ebp)在这里是错误的:在指令之后,EAX上面的两行包含指向指针的指针(不是指针本身)。所以你必须改为使用0x0(%eax)。

但是,您希望eax包含指针的旧值。正确?

所以你的代码应该是这样的:

push %ebp
movl %esp, %ebp
movl 0x8(%ebp),%ecx // <-- ecx holds a pointer to the pointer!
movl (%ecx),%eax    // <-- eax holds the old value
movl %ebp,(%ecx)    // <-- change the pointer
popl %ebp
ret

我仍然不明白为什么要将EBP的值写入指针,因为EBP不包含任何有用的值!

答案 2 :(得分:0)

试试这个,它只使用一个汇编程序指令并将样板留给编译器:

void changePointer(struct tcb *s)
{
    asm("movl %%esp, %0"
            : /* No output */
            : "m" (s->sp);
            : /* Nothing clobbered */
       );
}