回复 10楼 有容就大
1. 全是值传递2. 等晚上有时间我给详细写printf是怎么覆盖r的地址的

技术问题,请不要以短消息方式提问
程序代码:#include <stdio.h>
#include <stdlib.h>
typedef struct link
{
int data;
struct link* next;
}node;
node* p()
{ //what is ebp & esp? please google.
node *head,*p,*q,r; //we suppose after push ebp, esp = 0x1000; just easy to explain
//head address: ebp - 0x04 sizeof(head) = 4;
//p addr: ebp - 0x08 sizeof(p) = 4;
//q addr: ebp - 0x0C sizeof(q) = 4;
//r addr: ebp - 0x10 sizeof(r) = sizeof(node) = 8;
//so r addr: 0x1000 - 0x10 = 0xff0; remember this address 0xff0;
//how this happen?
//push ebp
//mov ebp, esp
//add esp, -(4 + 4 + 4 + 8) /just description/
//
head=(node*)malloc(sizeof(node)); //head->addr which alloc from free heap_block
p=(node*)malloc(sizeof(node)); //p->addr which alloc from free heap_block
q=(node*)malloc(sizeof(node)); //q->addr which alloc from free heap_block
head->next=p;
p->next=q;
p->data=1;
q->data=3;
q->next=&r;
r.data=4;
r.next=NULL;
return head; //return head->addr;
//head address: no longer valid
//p addr: no longer valid
//q addr: no longer valid
//r addr: no longer valid
//how this happen ?
//mov esp, ebp or other instructions
//pop ebp
//release the local variables addr
//esp return to 0x1000;
}
int main(int argc, char *argv[])
{
node *head,*ptr;
head=p();
ptr=head->next->next;
while(ptr->next!=NULL)
{
printf("%4d",ptr->next->data); //inside printf alloc local variables again
//push (ptr->next->data)
//push "%4d"
//call printf
// push ebp
// mov ebp, esp //still suppose ebp = 0x1000;
// sub esp, 0Ch
//means
//local variables occupies
// we didn't know printf will use how many local variables.
// but only if
//printf()
//{
// int pa,pb,pc,pd,pe....;
// pd and pe absolutely override the address 0xff0, and that's the r in function p
//}
ptr=ptr->next;
} //conclusion:
//different function will reuse the same stack in same process.
//don't return stack address or depend on it.
return 0;
}简单的写了下

程序代码:#include <stdio.h>
#include <stdlib.h>
typedef unsigned int uint32_t;
typedef unsigned int size_t;
typedef void*(*FUNC)();
typedef struct link
{
int data;
struct link* next;
}node;
node* p()
{
node *head,*p,*q,r;
return head;
}
node* q()
{
node *head,*p,*q,r;
return head;
}
struct __StackEmulator {
#define STACK_SIZE (512)
uint32_t mapped_stack[STACK_SIZE];
uint32_t mapped_esp;
uint32_t mapped_ebp;
}stk = {{0}, STACK_SIZE, -1};
void dumpStack(void)
{
uint32_t curr = (&stk)->mapped_esp;
while (curr < STACK_SIZE) {
printf("TRACE OUT SYS_STACK:%d = 0x%x\n", curr++, (&stk)->mapped_stack[curr]);
}
}
void func_loader(FUNC func, void *pram, size_t size)
{
(&stk)->mapped_stack[--(&stk)->mapped_esp] = (&stk)->mapped_ebp; //push ebp
(&stk)->mapped_ebp = (&stk)->mapped_esp; //mov ebp, esp
while (size-- > 0) {
(&stk)->mapped_stack[--(&stk)->mapped_esp] = *(((uint32_t*)pram)++); //local variables
}
dumpStack();
//execute func;
func();
//release process stack
(&stk)->mapped_esp = (&stk)->mapped_ebp; //mov esp, ebp
(&stk)->mapped_ebp = (&stk)->mapped_stack[(&stk)->mapped_esp++]; //pop ebp
}
int main(int argc, char *argv[])
{
uint32_t pram1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; //emulator pram of func p
uint32_t pram2[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60}; //emulator pram of func q
func_loader(p, (void*)pram1, sizeof(pram1)/sizeof(pram1[0]));
func_loader(q, (void*)pram2, sizeof(pram2)/sizeof(pram2[0]));
return 0;
}
这样你能看懂?
