Fab*_*ian 10 c function-pointers memory-layout
我刚刚学习了函数指针(指向存储函数机器代码的地址的指针).这让我想到机器代码以及它如何存储在内存中.
机器代码是否连续存储在内存中,以便可以"手动"增加指针,直到它指向下一个/上一个函数?
这是调试器的作用吗?他让我"看到"程序计数器指向机器代码的位置?
结论:可以用函数指针编程一个原始调试器吗?
我理解这是对的,还是我离开了?
使用我设法追踪的草案C标准(N1124),我们有类似的规则.关于加法表达式(第6.5.6/2节)的部分说明了这一点
另外,两个操作数都应具有算术类型,或者一个操作数应是指向对象类型的指针
对象类型在§6.2.5/ 1中定义为
存储在对象中或由函数返回的值的含义由用于访问它的表达式的类型确定.(声明为对象的标识符是最简单的表达式;类型在标识符的声明中指定.)类型被分区为对象类型(完全描述对象的类型),函数类型(描述函数的类型),以及不完整的类型(描述对象的类型,但缺少确定其大小所需的信息).
由于函数类型与对象类型不同,这表明禁止对函数指针进行指针运算.
在C++中,此操作是非法的.第5.7/1节中给出的指针加法的定义如下:
另外,两个操作数都应具有算术或枚举类型,或者一个操作数应是指向完全定义的对象类型的指针,另一个操作数应具有整数或枚举类型.
但是,§3.9/ 9表明了这一点
对象类型是(可能是cv限定的)类型,它不是函数类型,不是引用类型,也不是void类型.
总而言之,这意味着您无法在C++中增加函数指针.
希望这可以帮助!
有点儿。您假设函数将按照它们在源代码中的方式在内存中布局。最有可能的是,它们不会——编译器通常会随意移动它们。
然而,您可以做的是使用指向当前指令的指针逐步执行代码,并将计数器增加一定量以到达下一条指令。但是,在这种情况下,我们将不再将其称为函数指针,因为它不仅指向函数的开头,而且还指向函数的开头。相反,我们将其称为指令指针。
事实上,这正是计算机的工作原理——它有一个称为程序计数器的特殊寄存器,它始终指向当前指令,并在每条指令后将其递增一定的量(一条命令相当于将一个值写入程序)柜台)。GOTO
然而,在现实世界中,调试器并不是这样工作的——事实上,我什至不确定是否可以有一个指针指向 C 内存中的代码段,而不是函数指针。更有可能的是,只有在需要模拟程序计数器时才需要使用此技术,例如为另一种处理器类型编写模拟器。
你可以(或者至少可以)做这样的事情,但这显然是非平凡的.首先,你不能实际增加或减少一个函数指针 - 它指向一个地址,但是指针数学通常以sizeof(pointed to type)- 的增量完成- 但是有一个函数,这没有意义,所以你不能做数学就可以了.
大多数调试器(主要)通过使用与地址到行号,函数名,变量名等相关的调试信息来工作.