我正在阅读欧文第6版。教我自己组装,我在第277页(第8.2.2节“访问堆栈参数”,子标题'在堆栈上传递8位和16位参数')遇到了这句话,它说明了:
“虽然您可以将16位操作数推入堆栈,但这样做可以防止ESP在双字边界上对齐。可能会发生页面错误,并且运行时性能可能会降低。”
据我所知,由于内存访问的粒度,未对齐的内存访问可能会导致性能问题,但我不明白为什么会发生页面错误。根据我的理解,当进程使内存访问当前未加载到物理内存中的虚拟内存中的位置时,会发生(硬)页面错误。
1。因此,引用是说堆栈可能同时存在于多个页面中,并且未对齐可能会使后续的内存访问超过页面边界?
2。如果我已经回答了我自己的问题,那么将堆栈大小分配给一个页面的大小(即,在MASM中使用.STACK 4096
指令)强制堆栈在一页上连续存在,消除了这个问题?或者堆栈是否仍然位于两个不同的页面上?
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 ] |
---------------- ----------------
谢谢! (并且抱歉所有条件问题,如果我过度思考这个问题)