531035528 发表于 2025-9-23 16:03:20

问题3.12???

将10000h-1001fh设置为代码段,并输入如下代码:

mov ax,1000
mov ss,ax
mov sp,0020
mov ax,cs
mov ds,ax
mov ax,
add ax,
mov bx,
add bx,
push ax
push bx
pop ax
pop bx

设置CS=1000H,IP=0 一直执行到mov bx,变成了mov bx,|随后的代码全变了.....,请问是什么原因???

不二如是 发表于 2025-9-23 16:20:10

宝子把栈放在了代码段正中央,还开着单步/断点,结果“调试陷阱中断(单步 INT1/断点 INT3)”和你后面的 push 把数据写回了同一个段里的那些地址,把指令字节给改写了,所以 mov bx, (8B 1E 04 00) 被把最后一个字节 00 覆盖成了 C8,逆向器/调试器就把它反汇编成了 mov bx,,后面的指令也都“跟着变了”。

你是单步到 mov bx, 的。每执行完一条指令,CPU会触发单步中断 INT1,它会在当前 SS:SP 上压栈6字节(FLAGS, CS, IP),也就是把数据写到 1000:001A..001F。

而 mov bx, 这条指令的4个字节在 0013..0016,它的“最后一个字节 00”正好挨着。

前面几次单步的压栈把 001A..001F 改了,再加上你后续自己的 push ax/push bx(从 SP=0020 开始往下写 001E..),统统落在同一片 0000..0020 的代码区域,于是把指令字节覆盖,反汇编就“花”了——8B 1E 04 00 的 00 被写成了 C8,显示成了 (小端序 04 C8)。

简单说:

SS=DS=CS=1000h 且 SP=0020h,栈顶正砸在你的代码上;单步/中断/push 都会把“数据”写到“代码”上 → 代码被改。

把栈放到别的段,就可以{:13_439:} :

mov ax,2000h
mov ss,ax
mov sp,0100h
(注意先 mov ss,ax 再设 sp,而且在改 ss 附近最好避免中断)

同一段也行,但把 SP 设远一点,别压到代码:

mov ss,cs
mov sp,0100h    ; 甚至 0FFF0h 都行,只要不碰 0000..0020 的指令区
调试时别用单步在那么低的 SP:先把 SS:SP 调好,再开始单步;或者先一次性运行到安全位置再单步。

如果你故意要读代码里的字(mov ax, 之类),那没问题,但务必保证栈不覆盖这片区域。

照以上改一下,你就不会再看到 mov bx, 变成奇怪的指令了。

jackz007 发表于 2025-9-23 18:20:30

本帖最后由 jackz007 于 2025-9-23 18:45 编辑

       堆栈和代码使用了同一块只有 20H 字节(mov sp,0020)的存储空间,只要有数据进出堆栈,都会改变 sp 指针下方的内容,我们知道,在程序运行期间,不只是程序本身会使用堆栈,操作系统、调试器在我们不知情的情况下也会 "偷偷" 使用,假如在我们调试程序期间,操作系统和调试器曾经使用过 10H 的字节的堆栈空间,那么,从 SP 向下 10H 字节的存储区的内容就会被改变,而这个区域恰好储存有代码,这就是楼主代码被莫名其妙改变的直接原因。只要把堆栈空间放到足够大(mov sp,200h),足以避免覆盖代码数据即可解决问题。

531035528 发表于 2025-9-23 19:54:56

jackz007 发表于 2025-9-23 18:20
堆栈和代码使用了同一块只有 20H 字节(mov sp,0020)的存储空间,只要有数据进出堆栈,都会改变 sp ...

thanks{:5_108:}
页: [1]
查看完整版本: 问题3.12???