在学习此节中时,遇到书中的 程序6.4 有些疑问
assume cs:code, ds:data, ss:stack data segment dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h data ends stack segment dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 1. 这里为什么是16个字型数据 0? stack ends code segment start: mov ax, stack mov ss, ax mov sp, 20h ; 2. 这里为什么是 20h? mov ax, data mov ds, ax sub bx, bx mov cx, 8 s: push [bx] add bx, 2 loop s sub bx, bx mov cx, 8 s0: pop [bx] add bx, 2 loop s0 mov ax, 4c00h int 21h code ends end start
对于问题1,目前来说,我认为这里应该是 8 个字型的 0 就可以了,因为它是用于栈段的初始化,栈段用于操作上面的数据段的,数据段中的数据就是 8 个字。所以,我觉得这里没有必要用 16 个字的栈, 8 个就够了。
由于上述代码中采用的是16个字长的栈,那么根据
当栈为空时,ss:sp 指向栈底的下一个内存单元
所以16个字,也就是32个字节。sp是偏移地址,且偏移单位是字节,所以 sp 必须是十进制的32,也就是十六进制的20h。
引用的那段话的意思就是,假设现在有栈 1000:0 ~ 1000:000F,可见这个栈的长度是16个字节,也就是可以存放8字的数据,那么字型的数据将是下面的存放形式
1000:0-1000:1 1000:2-1000:3 1000:4-1000:5 1000:6-1000:7 1000:8-1000:9 1000:A-1000:B 1000:C-1000:D 1000:E-1000:F
可见最后一个字型占用的是 1000:E-1000:F,那么,当栈中只有最后一个字型的时候,ss:sp 指向的是 1000:E。栈为空,也就是将最后一个字型数据也从栈中 pop 出去,那么根据栈中数据 pop 的规则
可以得出,当最后一个字型弹出后,sp = Eh + 2,sp 为 10h。栈底是 1000:F, 1000:10 刚好就是栈底的下一个内存单元。
实际只修改了两个地方
ssume cs:code, ds:data, ss:stack data segment dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h data ends stack segment dw 0, 0, 0, 0, 0, 0, 0, 0 ; 8 个字的栈就够了 stack ends code segment start: mov ax, stack mov ss, ax mov sp, 16 ; 8 个字的栈,就是 16 个字节,sp 为十进制 0~15,当栈为空时,sp 指向栈底的下一个单元,也就是 16 mov ax, data mov ds, ax sub bx, bx mov cx, 8 s: push [bx] add bx, 2 loop s sub bx, bx mov cx, 8 s0: pop [bx] add bx, 2 loop s0 mov ax, 4c00h int 21h code ends end start