在学习此节中时,遇到书中的程序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
对于问题1,目前来说,我认为这里应该是 8 个字型的 0 就可以了,因为它是用于栈段的初始化,栈段用于操作上面的数据段的,数据段中的数据就是 8 个字。所以,我觉得这里没有必要用 16 个字的栈, 8 个就够了。
问题2
由于上述代码中采用的是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 = sp + 2
可以得出,当最后一个字型弹出后,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