assume cs:code,ds:data,ss:stack
data segment
db 'dju '
db 'kui '
db 'pio '
db 'mkn '
;dw 0
data ends
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax ;改行执行后,栈数据改变
```c
mov sp,16
mov bx,0
mov cx,4
s: ;mov ds:[40h],cx
push cx
mov si,0
mov cx,3
s0:mov al,ds:[bx+si]
and al,11011111b
mov ds:[bx+si],al
inc si
loop s0
add bx,16
;mov cx,ds:[40h]
pop cx
loop s
mov ax,4c00h
int 21h
code ends
end start
```
在汇编语言中,你将值分配给SS寄存器时,即你正在更改堆栈的段地址。
这意味着更改后堆栈指针(SP)将指向内存中的不同位置。
在代码中,首先将DS寄存器设置为指向数据段,然后将SS寄存器设置为指针指向堆栈段。
当你执行指令“mov sp,16”时,您将堆栈指针设置为指向堆栈段内的偏移量16。
然后,在标记为“s”的循环中,将CX寄存器推送到堆栈上,然后修改数据段中的一些数据。此数据修改不应以任何方式影响堆栈段。
然而,当你执行指令“pop cx”时,你会将cx的值从堆栈中弹出并返回到寄存器中。由于之前SS寄存器的变化导致堆栈指针发生了变化,因此实际上是从内存中不同的位置弹出值,而不是从之前推送它的位置弹出。这就是您在堆栈数据中看到意外变化的原因。
为了避免这个问题,你应该确保只访问当前堆栈帧边界内的堆栈,并且在修改SS寄存器或堆栈指针时要小心。