请教大家一个关于汇编的问题。

2021-07-18 17:16:50 +08:00
 Danswerme

在学习王爽的《汇编语言第三版》时,有个示例要求利用栈将程序中的数据逆序存放;无论是作者的例子,还是我稍微修改后的程序运行结果都没有问题,但是不知道为什么栈内的内容总是和预期的不一致,请大家帮我解答一下。

作者的例子如下:



我觉得既然只是逆序存放 8 个字型数据,那就用 dw 定义 8 个字型数据就行了,无需 16 个;然后我就重新只定义了 8 个字型数据,同时将初始的栈顶偏移地址改为了 20H 。


然后用 DEBUG 进行调试,跳转到第一次循环结束的地方,入栈的结果 076A:10 1F 是正常的,但是原数据的后四个 076A:8 F 被改写了。


再次跳转到程序结尾部分,逆序存放的结果 076A:0 F 是正确的,但是栈的后四位 076A:18 1F 又被改写了。


用 DEBUG 调试了一下作者的示例程序,发现也存在这样的情况,不仅栈的后四位 076A:28 2F 被改写了,就连没有使用的 076A:1A 1F 也被改写了。究竟是什么原因导致这些地方总是被改写了呢?


1378 次点击
所在节点    问与答
8 条回复
dic
2021-07-18 17:26:20 +08:00
我看的是 《汇编语言第四版》,在学习过程中也发现了这个情况,不过书上说是由于中断导致的,让先不用管这种情况后续内容中会有说明。
Danswerme
2021-07-18 17:39:27 +08:00
@dic 谢谢,那我先往下看吧。
senghoo
2021-07-18 19:32:14 +08:00
好久没看汇编了。仅仅猜测哈。
这应该是传说中的 Stack overflow 吧。sp 寄存器下面(小于此地址的内存,stack 来说是上方)的空间被认为是空闲空间,中断处理程序什么的有可能用到空间。

第一次循环结束时 sp=0x10,这时候其实栈已经满了(再往下走就是原始数据了),如果这个时候中断处理程序介入,就会覆盖原始数据。第二次循环结束时同理,你已经释放了栈空间( sp=20),如果这时候中断来,数据有可能改写。

盲猜,要是有大佬请指正哈~~
irytu
2021-07-18 20:35:50 +08:00
@senghoo 中断处理应该是 trap 到内核 用的内核栈 怎么覆盖用户进程的 stack ?
Danswerme
2021-07-18 21:59:23 +08:00
@senghoo 还没看到中断这,等看到后面了再翻回来悄悄。
senghoo
2021-07-18 22:53:52 +08:00
@irytu 这个是 x86 实模式下的吧,应该不涉及到内核态。中断发生时应该分别入栈标志寄存器、CS 还有 IP 。所以第一个 DosBox 的图 076A:000A-000F 分别是 00 35 ( IP )、6A 07(CS)、A3 01 ( FLAG) 应该能对的上。
senghoo
2021-07-18 22:56:01 +08:00
@senghoo @irytu IP 写错了应该是 35 00
irytu
2021-07-18 23:31:27 +08:00
@senghoo 嗯 你说的对 原来是实模式… 没注意

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/790217

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX