如何从程序集更改指针值(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 */ ); }