汇编中给ss赋值,为什么栈内数据改变?

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寄存器或堆栈指针时要小心。