关于《汇编语言(王爽)》程序6.3使用16个dw 0的问题

在学习王爽老师《汇编语言》的第6.2节时,在程序6.3代码中,给出了以下的代码:oop

 1 assume cs:code
 2 code segment
 3     dw 0123h, 0456h, 0789h, 0abch,  0123h, 0456h, 0789h, 0abch
 4     dw 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
 5 
 6 start: mov ax,cs
 7     mov ss,ax
 8     mov sp,30h
 9     
10     mov bx,0h
11     mov cx,8
12 s:  push cs:[bx]
13     add bx,2
14     loop s
15 
16     mov bx,0
17     mov cx,8
18 s0: pop cs:[bx]
19     add bx,2
20     loop s0
21 
22     mov ax,4c00h
23     int 21h
24 code ends
25 end start

能够看到第4行中定义了16个dw 0,也就是16个字型数据(32个字节型),随后将该32个字节内存空间当作栈来使用。初始栈顶为30h,结构图以下:学习

从上图能够看到,总共花费了48个字节,48转换成16进制值为30H,而内存地址从0开始计数,所以这2个dw的内存起止地址为0~2F,上面的代码将第二个dw段视做栈空间,初始栈为空,所以指向栈下面的内存空间,结构以下:spa

因此代码的第8行将栈偏移地址寄存器SP设置为30h。调试

这里有一个问题,第一个dw段只定义了8个字型数据(16个字节),为了逆序反转它,应该只须要8个字型大小的栈空间,但实际却定义了16个字型数据(32个字节),多出来8个字型数据,彷佛是多余的。更改代码,将第二个dw段中定义的16个字型数据更改成8个,这样栈偏移地址寄存器SP就应该设置为20h,而后调试程序看看,以下:code

首先回忆书本第4章4.9节程序执行过程的跟踪中的说明,一个程序的加载必定是先找到一段足够空间的内存,该内存空间的地址段为SA,偏移地址为0,所以寄存器CS=SA,寄存器IP=0h。而该内存前面256个字节用来和程序通讯,所以实际的指令段地址为CS=CS+10h。blog

上机查看加载到内存的代码指令,能够看到IP寄存器的值的确为20h,由于前面32个字节是数据空间,第33个字节才是真正指令,所以IP指向20h(这是程序源码中start标志告诉编译器的)。另外,也能够看到第一个压栈的循环在0B34:002D~0B34:0033处。内存

 

在执行循环压栈数据以前,先查看代码指令前20个字节的空间的值,也就是2个dw段中定义的数据。而后一次性执行完第一个循环,使用g命令,令其执行到0B34:0035处开始等待,而后再查看一次前20字节的数据空间,以下:编译器

从上图能够发现一个比较奇怪的地方,那就是栈空间的数据并无改变,第一个dw段的数据没有压栈。这不该该,为何没有正常工做?再次查看代码指令,忽然发现代码指令被改写了,以下图:源码

因为指令被改写,那天然上面的程序就没发正常工做了。那为何指令的内容会被改变呢?回想书本第3章最后一个问题,也就是实验2中最后一个提问,为何栈里的数据改变了?编译

最前面的程序使用16个dw字型数据作栈空间时,可以正常工做,而使用8个字型数据时,则出现了问题,这缘由是否是和上面图中的提问的答案同样?

相关文章
相关标签/搜索