在C语言中,如何给指针赋值?

在C语言中,如何给指针赋值?,c,C,我正在为指令集架构创建一个模拟器,我需要实现一个堆栈结构。我决定我的%eip、%ebp和%esp将是int指针。但是,在某些情况下,我需要在堆栈上存储内存地址,在这种情况下,该内存将被编码为整数值。但是当我返回这个值时,我需要把它放回我的指令指针中,它被实现为一个int指针。C不允许我将整数分配给int指针,因此我无法从“堆栈”中恢复这些内存地址。有什么建议吗 它是实现定义的,但如果整数宽度不小于指针,则可以这样使用 有人说使用ptrdiff_t和NULL指针作为参考更方便、更安全 ptrdif

我正在为指令集架构创建一个模拟器,我需要实现一个堆栈结构。我决定我的%eip、%ebp和%esp将是int指针。但是,在某些情况下,我需要在堆栈上存储内存地址,在这种情况下,该内存将被编码为整数值。但是当我返回这个值时,我需要把它放回我的指令指针中,它被实现为一个int指针。C不允许我将整数分配给int指针,因此我无法从“堆栈”中恢复这些内存地址。有什么建议吗

它是实现定义的,但如果整数宽度不小于指针,则可以这样使用

有人说使用
ptrdiff_t
NULL
指针作为参考更方便、更安全

ptrdiff_t myptrdiff = myptr - (type_of_myptr *)NULL;

myptr = myptrdiff + (type_of_myptr *)NULL; 
我决定我的%eip、%ebp和%esp将是int指针

这不是一个合理的架构决策。你需要重新考虑一下

  • 指针的大小取决于体系结构——特别是在64位系统上,
    int*
    的宽度为64位。相比之下,所有这些寄存器定义为32位宽。使用64位指针存储其值将导致意外行为

  • 这些寄存器不需要与整数对齐。特别是,EIP(最多)与指令对齐,并且在运行1字节指令时将增加1字节。延迟未正确对齐的
    int*
    将在许多系统上导致未对齐的访问故障

  • 任何整数寄存器(EA/B/C/DX、ESP、EBP、ESI、EDI)之间都没有严格的体系结构区别。所有这些都可以在ModRM编码中引用,并且可以视为数值或地址,具体取决于上下文。单独使用ESP和EBP将不必要地使仿真器复杂化,并可能在代码中产生许多令人讨厌的特殊情况


  • 请注意,当您在可能不是32位平台的平台上模拟32位系统时,您将需要某种方式将模拟系统中的地址转换为主机进程中的“真实”地址。有许多不同的方法可以做到这一点;哪一个最适合您将取决于您的具体目标。

    要将
    int
    值分配给
    int*
    对象,请使用显式强制转换,如下所示:

    destination = (int *) source;
    

    您的问题是“C不允许我将整数指定给int指针”,但无法确切说明问题所在。您可能从编译器获得了一些诊断信息。这是因为将
    int
    值指定给
    int*
    对象违反了C标准的赋值约束。上面的代码展示了如何解决这个问题


    这就解决了编译器诊断的直接问题。但是,使用
    int
    值作为指针的容器可能存在各种问题,包括陷阱值的可能性以及指针和整数大小之间的差异。假设
    int
    int*
    的大小相同,使用
    int
    来保存
    int*
    不太可能有效,但您应该确定C实现的属性。

    “C不允许我将整数分配给我的int指针”-到底发生了什么?你试过投吗
    int*iptr=(int*)您的_int
    需要您的代码。没有代码就无能为力。也许您可以转换
    uintptr\u t
    ,这是一种在
    中定义的类型,当它在您的计算机上可用时(通常是可用的,尽管理论上是可选类型)。或者您可能只需要添加一个显式强制转换。如果您收到关于不同大小的整数和指针的警告,那么您需要更加担心。对这些寄存器使用无符号非指针类型更有意义,因此您可以对它们执行无符号算术,而无需强制转换。对于您执行的几乎所有指令,您都需要这个。毕竟,在访问实际数据之前,您可能需要进行一些地址转换。您也不太可能在模拟器和模拟器运行的代码之间混淆地址空间。还要确保您的无符号类型足够宽,可以存储模拟体系结构的地址。这是关于OP的代码和设计的注释,而不是对他们问题的回答。它可以是注释,但不应作为答案输入。此外,关于第2项,OP的目的是在
    int
    对象中存储指针,而不是在
    int*
    对象中存储任意指针。他们之所以提到
    int*
    ,是因为他们的%eip、%ebp和%esp都有
    int*
    ,但他们要存储的指针将位于其中一个指向的
    int
    中。@EricPostChil重新阅读OP关于他们将数据从堆栈弹出到这些寄存器的问题的描述。我很清楚,他们试图使用指针本身——而不是它所指向的值——作为寄存器值。关于弹出数据,问题是“…我需要把它放回指令指针,它被实现为int指针。”因此,他们没有使用
    int*
    作为任意值的存储容器。它们正在还原为
    int*
    某个值,该值是为
    int*
    准备的,即%eip。他们的“%eip”是
    int*
    的事实表明,他们正在模拟的ISA具有固定的指令大小,因此它的所有有效值也都是有效的
    int*
    值。在任何情况下,他们都不会使用
    int*
    作为任意值的载体,而只是用于指定的值。类似地,您对ModRM等的评论表明您采用的是x86体系结构,OP没有认可