我正在为指令集体系结构创建一个仿真器,并且我需要实现一个堆栈结构。我决定将我的%eip,%ebp和%esp用作int指针。但是,在某些情况下,我需要在堆栈上存储内存地址,在这种情况下,该内存将被编码为整数值。但是,当我返回该值时,需要将其放回指令指针中,该指令指针是作为int指针实现的。 C不允许我将整数分配给我的int指针,因此我无法从“堆栈”中恢复这些内存地址。有什么建议么?
答案 0 :(得分:1)
要将int
值分配给int *
对象,请使用显式强制转换,如下所示:
destination = (int *) source;
您的问题是“ C不会让我将整数分配给我的int指针”,但无法准确说明问题所在。大概是从编译器中获得一些诊断消息。这是因为将int
值分配给int *
对象会违反C标准的分配约束。上面的代码显示了解决方法。
这解决了编译器诊断的直接问题。但是,将int
值用作指针的容器可能会有各种问题,包括陷阱值的可能性以及指针和整数大小之间的差异。假设int
和int *
的大小相同,使用int
来容纳int *
的可能性不大,但是您应该确定C的属性实施。
答案 1 :(得分:0)
它是实现定义的,但是如果整数宽度不小于指针-您可以通过这种方式使用它。
有人说使用ptrdiff_t
和NULL
指针作为参考更加可移植和安全。
ptrdiff_t myptrdiff = myptr - (type_of_myptr *)NULL;
myptr = myptrdiff + (type_of_myptr *)NULL;
答案 2 :(得分:0)
我认为我的%eip,%ebp和%esp将是int指针。
这不是一个合理的架构决定。您需要重新考虑。
指针的大小与体系结构有关-特别是,int *
在64位系统上将为64位宽。相比之下,所有这些寄存器在定义上均为32位宽。使用64位指针存储其值将导致意外行为。
这些寄存器不需要与整数对齐。特别是,EIP(最多)与一条指令对齐,并且在运行1字节指令时将增加1个字节。延迟未正确对齐的int *
会在许多系统上导致未对齐的访问错误。
任何整数寄存器(EA / B / C / DX,ESP,EBP,ESI,EDI)之间都没有硬性体系结构上的区别。所有这些都可以用ModRM编码引用,并且可以根据上下文被视为数字值或地址。单独使用ESP和EBP将不必要地使仿真器复杂化,并且可能在代码中创建许多令人讨厌的特殊情况。
请注意,当您在可能不是32位平台的位置上模拟32位系统时,将需要某种方式将模拟系统内的地址转换为主机进程中的“实际”地址。有很多不同的方法可以做到这一点。哪一个最适合您取决于您的特定目标。