OpenBuild 发表于 2023-11-17 21:15

新人 汇编问题求助

本帖最后由 OpenBuild 于 2023-11-17 21:16 编辑

为什么2000:0~2000:f中的内容会发生改变?
我自己本身的理解就是,在你划分这个区域0~F这个区域为栈段的时候,CPU也同时用到了 这块区域的,所以这里才出现数据。
我不知道这样理解的有没有问题,求大佬指点指点。

heartingrass 发表于 2023-11-18 12:05

本帖最后由 heartingrass 于 2023-11-18 12:32 编辑

此处涉及debug调试底层细节:
一是 使用单步调试的时候,如果遇到修改SS栈段寄存器,会自动执行下面的一条语句
二是 修改新的SS栈段的前10个字节,是因为修改栈段时,保护现场运行环境,依次将标志寄存器值、CS、IP、SS压入新的堆栈,
三是 为什么会在修改SS值后,要将SP置为10,就是因为第二点,里面的数据是调试工具或系统修改的,而非程序本身的操作,为了安全,所以就不用此部分数据
四是 为什么好多代码在编写的时候,不从0000开始,而是从0100开始,估计原因与第二点类似

OpenBuild 发表于 2023-11-18 14:59

heartingrass 发表于 2023-11-18 12:05
此处涉及debug调试底层细节:
一是 使用单步调试的时候,如果遇到修改SS栈段寄存器,会自动执行下面的一条 ...

第四点 我还是有点雾水,就是即便是从0100开始 ,新的栈段的前十个字节还是会受调式工具的影响,产生CS,IP,SS的数据。是0000还是0100开始不都是没有区别吗?大佬

问题1,开辟新栈段里面工具和系统产生的数据,对于push 和pop指令不受影响。对栈段也没有影响对不对?

SONIC3D 发表于 2023-11-19 13:53

本帖最后由 SONIC3D 于 2023-11-19 13:59 编辑

OpenBuild 发表于 2023-11-18 14:59
第四点 我还是有点雾水,就是即便是从0100开始 ,新的栈段的前十个字节还是会受调式工具的影响,产生CS,I ...
debug插入的,用来从debug的逻辑回你程序代码时保护现场用,不影响你代码逻辑中的push pop

你可以这样对比下:
1. 在你第1次输入d 2000:0000 f查看后,可以看到此时的SS:SP是0B39:FFEE
2. 不要执行代码(或者只执行1句你第一行的不修改ss和sp的代码),然后立刻输入一下d 0B39:FFDE f,看看这时候栈上的0x10个字节,和你后来切换过ss,sp后查看d 2000:0 f作一个对比
3. 然后你可以额外再push一个数据到当前栈中,看看在debug中显示它实际会被push在什么位置。

或者可以留意一下: https://thestarman.pcministry.com/asm/debug/debug2.htm#G
这段的末尾有一段话: "Technical Notes: The "User" stack pointer must be valid and have 6 bytes available for this command to function correctly. An iret instruction is used to jump to the first breakpoint encountered. DEBUG sets the User Stack Pointer and pushes the user Flags, the Code Segment register and the Instruction Pointer onto the User Stack. So if the User Stack is not valid or is too small, the operation might crash."

另外你代码中之所以执行mov ss,ax后单步中断跳过了mov sp,10,是因为这个是ss被mov指令修改时的特性,会屏蔽中断,直到下一句代码执行完成(具体见https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-2b-manual.pdf的4-36页最下方2节以及该页底部的附注1),但是这个和你这里内存被改动没有关系。
页: [1]
查看完整版本: 新人 汇编问题求助