【发布时间】:2011-02-24 18:19:24
【问题描述】:
这个问题与我目前看到的任何错误无关,它更多的是关于理论和接受有关硬件架构设计和实施变化的教育。
场景 1: 假设 16 位处理器具有 16 位寄存器、16 位寻址和 sizeof(int) = 16 位:
unsigned int a, b, c, d;
a=0xFFFF;
b=0xFFFF;
c=a+b;
c 旁边的内存位置是否可以被覆盖?
(在这种情况下,我希望在 add 操作期间会引发溢出标志,并且c 要么保持不变,要么被未定义的数据填充。)
场景 2: 假设 32 位处理器具有 32 位寄存器,32 位寻址,sizeof(int) = 32 位,sizeof(short int)=16 位:
unsigned int a, b;
unsigned short int c, d;
a=0xFFFF;
b=0xFFFF;
c=a+b;
c 旁边的内存位置是否可以被覆盖?
(我希望在添加操作期间不会引发溢出标志,但是在分配操作期间是否引发内存访问或溢出标志将取决于硬件的实际设计和实现。如果d位于同一 32 位地址位置的高 16 位(可能甚至不可能使用 32 位寻址),它可能会被覆盖。)
场景3:假设32位处理器有32位寄存器,16位寻址,sizeof(int) = 32位,sizeof(short int)=16位:
unsigned int a, b;
unsigned short int c, d;
a=0xFFFF;
b=0xFFFF;
c=a+b;
c 旁边的内存位置是否可以被覆盖?
(我希望在类型转换和赋值操作期间会引发一些溢出标志或内存违规标志。)
场景 4: 假设 32 位处理器具有 32 位寄存器、32 位寻址和 sizeof(int) = 32 位:
unsigned int a, b;
struct {
unsigned int c:16;
unsigned int d:16;
} e;
a=0xFFFF;
b=0xFFFF;
e.c=a+b;
是否可以覆盖c 旁边的内存位置,即d? (在这种情况下,由于 c 和 d 预计驻留在同一个 32 位地址中,并且两者在技术上都是 32 位整数,因此可以想象在加法或赋值期间不会引发溢出标志,并且 d可能会受到影响。)
我没有尝试在实际硬件上对此进行测试,因为我的问题更多是关于理论以及设计和实现的可能变化。任何见解将不胜感激。
- 导致溢出的二进制整数运算是否可能覆盖相邻的内存?
- 目前是否有任何硬件实现遇到类似的内存覆盖问题,或者过去是否有系统存在此问题?
- 典型的处理器使用什么设备来防止相邻内存被算术和赋值操作覆盖?
【问题讨论】:
-
这不是更多关于特定语言的实现(看起来像 C)如何处理将整数分配给较小整数类型的变量吗?
-
我会说答案是“不,对于任何合理的架构和编程语言” - 但请参阅 The Story of Mel 以了解在旧架构上可能发生的情况 可能... :-)
-
@delnan:是的,这个问题可能在很大程度上依赖于语言,但由于所有语言在运行之前都必须转换为机器代码,因此在硬件级别上它们都有一个共同点。这些示例使用类似 C 的语法,因为我相信大多数 SO 读者最容易使用这种语法。类似汇编的语法可能更适合这些问题,但可能无助于理解我的观点......然后再一次,用机器代码构建它可能只会给我提供“啊哈!”我正在寻找的洞察力。
-
但是所有语言,甚至 C 语言,都定义了自己的一套规则。有些人可能会指定非常严格的截断规则,而另一些人可能会未定义。
标签: memory-leaks theory overflow cpu-architecture