宝子把
栈放在了代码段正中央,还开着单步/断点,结果“调试陷阱中断(单步 INT1/断点 INT3)”和你后面的 push 把数据写回了同一个段里的那些地址,把指令字节给改写了,所以 mov bx,[4] (8B 1E 04 00) 被把最后一个字节 00 覆盖成了 C8,逆向器/调试器就把它反汇编成了 mov bx,[C804],后面的指令也都“跟着变了”。
你是单步到 mov bx,[4] 的。每执行完一条指令,CPU会触发单步中断 INT1,它会在当前 SS:SP 上压栈6字节(FLAGS, CS, IP),也就是把数据写到 1000:001A..001F。
而 mov bx,[4] 这条指令的4个字节在 0013..0016,它的“最后一个字节 00”正好挨着。
前面几次单步的压栈把 001A..001F 改了,再加上你后续自己的 push ax/push bx(从 SP=0020 开始往下写 001E..),统统落在同一片 0000..0020 的代码区域,于是把指令字节覆盖,反汇编就“花”了——8B 1E 04 00 的 00 被写成了 C8,显示成了 [C804](小端序 04 C8)。
简单说:
SS=DS=CS=1000h 且 SP=0020h,栈顶正砸在你的代码上;单步/中断/push 都会把“数据”写到“代码”上 → 代码被改。
把栈放到别的段,就可以

:
- 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,[0] 之类),那没问题,但务必保证栈不覆盖这片区域。
照以上改一下,你就不会再看到 mov bx,[4] 变成奇怪的指令了。