巨大指针中的归一化是什么意思 [英] what is meant by normalization in huge pointers

查看:91
本文介绍了巨大指针中的归一化是什么意思的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在理解远"指针和巨大"指针之间的区别时,我有很多困惑,他们在Google各处搜索了一个解决方案,但找不到.谁能解释一下两者之间的区别.另外,与大指针相关的确切归一化概念是什么.

I have a lot of confusion on understanding the difference between a "far" pointer and "huge" pointer, searched for it all over in google for a solution, couldnot find one. Can any one explain me the difference between the two. Also, what is the exact normalization concept related to huge pointers.

请不要给我以下或任何类似的答案:

Please donot give me the following or any similar answers:

远指针和大指针之间的唯一区别是,大指针由编译器进行规范化.规范化指针是指在段中具有尽可能多地址的指针,这意味着偏移量永远不会大于15的大指针仅在对其执行了指针算术后才被规范化;在进行赋值时不被规范化.您可以通过递增和递减它来更改其值而无需更改其值.小于16,因为该段可以表示大于或等于16的任何值(例如,以规范化形式表示的绝对地址0x17将为0001:0001.虽然far指针可以使用0000:0017寻址绝对地址0x17,因为偏移量大于0000F,所以这不是有效的巨大(归一化)指针.)也可以使用算术运算符对巨大的指针进行递增和递减操作,但是由于归一化了它们,因此它们不会像far指针那样包装." >

"The only difference between a far pointer and a huge pointer is that a huge pointer is normalized by the compiler. A normalized pointer is one that has as much of the address as possible in the segment, meaning that the offset is never larger than 15. A huge pointer is normalized only when pointer arithmetic is performed on it. It is not normalized when an assignment is made. You can cause it to be normalized without changing the value by incrementing and then decrementing it. The offset must be less than 16 because the segment can represent any value greater than or equal to 16 (e.g. Absolute address 0x17 in a normalized form would be 0001:0001. While a far pointer could address the absolute address 0x17 with 0000:0017, this is not a valid huge (normalized) pointer because the offset is greater than 0000F.). Huge pointers can also be incremented and decremented using arithmetic operators, but since they are normalized they will not wrap like far pointers."

在这里对归一化概念的解释不是很好,或者可能是我无法很好地理解它.

Here the normalization concept is not very well explained, or may be I'm unable to understand it very well.

任何人都可以尝试从初学者的角度解释这个概念.

Can anyone try explaining this concept from a beginners point of view.

谢谢, 拉哈马特

推荐答案

8086最初是8位处理器8085的扩展.8085只能使用其16位地址总线寻址65536字节.英特尔开发8086时,他们希望该软件与旧的8位处理器尽可能兼容,因此,他们引入了分段存储器寻址的概念.这使得运行8位软件可以在更大的地址范围内运行,而不会引起注意. 8086具有20位地址总线,因此可以处理多达1 MB的内存(2 ^ 20).不幸的是,它无法直接寻址该存储器,因此必须使用段寄存器来实现.实际地址是通过将向左移动了4的16位段值加到16位偏移量的左边来计算的.

In the beginning 8086 was an extension of the 8 bit processor 8085. The 8085 could only address 65536 bytes with its 16 bit address bus. When Intel developed the 8086 they wanted the software to be as compatible as possible to the old 8 bit processors, so they introduced the concept of segmented memory addressing. This allowed to run 8 bit software to live in the bigger address range without noticing. The 8086 had a 20 bit address bus and could thus handle up to 1 MB of memory (2^20). Unfortunatly it could not address this memory directly, it had to use the segment registers to do that. The real address was calculated by adding the 16 bit segment value shifted by 4 to the left added to the 16 bit offset.

Example:
Segment  0x1234   Offset 0x5678 will give the real address
   0x 1234
  +0x  5678
  ---------
  =0x 179B8

您会注意到,此操作不是双射的,这意味着您可以使用段和偏移量的其他组合来生成实际地址.

As you will have noticed, this operation is not bijective, meaning you can generate the real address with other combinations of segment and offset.

   0x 1264               0x 1111
  +0x  5378             +0x  68A8
  ---------             ---------     etc.
  =0x 179B8             =0x 179B8

实际上,由于3个重叠的半字节(3*4 = 12位,2^12 = 4096),可能有4096种不同的组合. 归一化的组合是4096个可能值中的唯一一个,它将3个高半字节的偏移量设置为零.在我们的示例中为:

There are in fact 4096 different combinations possible, because of the 3 overlapping nibbles (3*4 = 12 bits, 2^12 = 4096) . The normalized combination is the only one in 4096 possible values that will have the 3 high nibbles of the offset to zero. In our example it will be:

   0x 179B
  +0x  0008
  ---------
  =0x 179B8

farhuge指针之间的区别不在规范化中,您可以使用未规范化的huge指针,这是绝对允许的.区别在于执行指针算术时生成的代码.使用远指针时,将指针增加或添加值时将不会发生溢出处理,并且您将只能处理64K内存.

The difference between a far and a huge pointer is not in the normalisation, you can have non normalised huge pointer, it's absolutly allowed. The difference is in the code generated when performing pointer arithmetic. With far pointers when incrementing or adding values to the pointer there will be no overflow handling and you will be only able to handle 64K of memory.

char far *p = (char far *)0x1000FFFF;
p++;
printf("p=%p\n");

将打印1000:0000 对于巨大的指针,编译器将生成处理结转所需的代码.

will print 1000:0000 For huge pointers the compiler will generate the code necessary to handle the carry over.

char huge *p = (char huge *)0x1000FFFF;
p++;
printf("p=%p\n");

将打印2000:0000

这意味着您在使用远或大指针时必须要小心,因为使用它们的算术成本不同.

This means you have to be careful when using far or huge pointers as the cost of the arithmetic with them is different.

也不应忘记,大多数16位编译器的库无法正确处理这些情况,因此有时会出现错误的软件. 微软的实模式编译器并未在其所有字符串函数上处理巨大的指针. Borland甚至更糟,因为即使mem函数(memcpymemset等)也无法处理偏移量溢出.这就是为什么将归一化的指针与这些库函数一起使用是一个好主意的原因,它们偏移偏移的可能性更低.

One should also not forget that most 16 bit compilers had libraries that didn't handle these cases correctly giving sometimes buggy software. Microsofts real mode compiler didn't handle huge pointers on all its string functions. Borland was even worse as even the mem functions (memcpy, memset, etc.) didn't handle offset overflows. That was the reason why it was a good idea to use normalised pointers with these library functions, the likelyhood of offset overflows was lower with them.

这篇关于巨大指针中的归一化是什么意思的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆