我在c:__asm__("mov $10, %rsi"); printf("%x")
中输入此代码,打印a
我在gdb
中调试它,发现结果存储为int register esi
问题:结果为esi
的原因是什么?
答案 0 :(得分:11)
printf("%x")
试图得到第二个参数,但它不存在,所以它只是读取应该存在的内存,找到那里的垃圾,然后打印出来。
简而言之:它是未定义的行为。
编辑:您看到与esi
寄存器中的值相同的原因是,此值是作为程序中某些早期(但最近)计算的一部分计算并存储的在同一位置printf
尝试阅读。两个位置重合的事实纯粹是偶然的,在未定义行为的范围内。
答案 1 :(得分:2)
当调用printf("%x")
时,会发生它所需的参数被推送到堆栈(以相反的顺序),最终,使用汇编命令call
调用该函数。在提供格式字符串"%x"
时,printf()
期望至少有一个参数,因此它将读取堆栈旁边的值,这可能是任何东西......
所以这种行为实际上是未定义的,通常是漏洞利用的原因,因为你可以破坏堆栈。
关于这个话题可能有点excourse。