标签:汇编 ola 就是 数据 class 理解 字符串 可变参数 第一个
今天看到一个问题,我们怎么确定printf中的可变参数。
这样,我们先从汇编的角度去理解一个东西,栈
char *p = (char*)malloc(256 << 20) + (256 << 20); __asm__ volatile("movl %0, %%rsp\n", "r"(p));
这段代码的意思很简单,我们分配了256MB字节长度的空间,让sp寄存器指向这段空间的末尾
每次推元素入栈,都会执行指令inc sp,然后把数据放入ss:sp
所以栈中的空间一定是先入栈的地址高,后入栈的地址低
好的,理解了这个,再来看这段代码
void f(int a, int b, int c, int d){ printf("%d", &a); printf("%d", &b); printf("%d", &c); printf("%d", &d); }
运行之后,发现a的地址最低,d的地址最高,每个参数间只差了一个sizeof int的大小
这说明d先入栈,然后c,b,a,入栈的地址是连续的,我们理解了这个,就能解开printf的面纱了
void f(const char * fmt, ...) { char* p; p = ((char*)&fmt) + sizeof(fmt); printf("%d\n", *(int*)p); p = p + sizeof(int); printf("%d\n", *(int*)p); p = p + sizeof(int); printf("%s\n", *((char**)p)); } int main() { f("%d %d %s\n", 4, 5, "hello world"); return 0; }
在f中,标准字符串fmt的地址在最低处,然后我们用它的地址加上它本身的地址,就是第一个参数的地址
通过读取fmt的内容确定其类型(虽然我直接写的hhh
然后用该类型指针输出这个地址的内容,直到读到fmt的末尾
这个函数的实现,说明了C/C++在编程上对地址操作巨大的自由性,比较神奇。
标签:汇编 ola 就是 数据 class 理解 字符串 可变参数 第一个
原文地址:https://www.cnblogs.com/Hebut-Amadeus/p/13149483.html