1

我目前正在阅读欧文第 6 版。教自己组装,我在第 277 页遇到了这句话(第 8.2.2 节,“访问堆栈参数”,子标题“在堆栈上传递 8 位和 16 位参数”),它指出:

“虽然您可以将 16 位操作数压入堆栈,但这样做会阻止 ESP 在双字边界上对齐。可能会发生页面错误并且运行时性能可能会降低。”

我知道由于内存访问的粒度,未对齐的内存访问可能会导致性能问题,但我不明白为什么会发生页面错误。据我了解,当进程对当前未加载到物理内存中的虚拟内存中的位置进行内存访问时,会发生(硬)页面错误。

1.因此,引用是否说堆栈可能同时存在于多个页面中,并且未对齐可能会使后续的内存访问超出页面边界?

2.如果我已经回答了我自己的问题,将堆栈大小分配为正好是一页的大小(即,使用.STACK 4096MASM 中的指令)会强制堆栈恰好在一页上连续存在,从而消除这个问题吗?或者堆栈可能仍然驻留在两个不同的页面上?

3.如果后者为真,那么填充数据(这是建议的)是否仍然会导致页面错误?例如:如果 16 字节变量是 'val1',并且我们想要访问它后面的一个名为 'val2' 的 dword,并且堆栈驻留在两个页面中,页面对齐到 0x1000:

Before padding After padding           ---------------- ----------------          0x1002 | [val1] | 0x1002 | [ PADDING ] |          0x1000 | [val2 high] | 0x1000 | [val1] |          --PG BOUNDARY--- ---PG BOUNDARY--          0x0FFE | [val2 low ] | PG FAULT! 0x0FFE | [val2 high] |PG FAULT! 0x0FFC | [irrelevant] | 0x0FFC | [val2 low ] |          ---------------- ----------------        

谢谢!(对不起所有的条件问题,如果我想太多了)

4

0 回答 0