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

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

#include #include 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 

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

 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不包含任何有用的值!

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

它不叫“组装”,它被称为“汇编”!

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

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