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

 assume cs:code
code segment
dw 0123h, 0456h, 0789h, 0abch, 0123h, 0456h, 0789h, 0abch
dw ,,,, ,,,, ,,,, ,,, start: mov ax,cs
mov ss,ax
mov sp,30h mov bx,0h
mov cx,
s: push cs:[bx]
add bx,
loop s mov bx,
mov cx,
s0: pop cs:[bx]
add bx,
loop s0 mov ax,4c00h
int 21h
code ends
end start

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

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

所以代码的第8行将栈偏移地址寄存器SP设置为30h。

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

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

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

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

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

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

最前面的程序使用16个dw字型数据做栈空间时,能够正常工作,而使用8个字型数据时,则出现了问题,这原因是不是和上面图中的提问的答案一样?

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

  1. 王爽汇编语言(第三版)环境搭建(附PDF及工具下载)

    一.前言 最近在学习汇编语言,使用的是读者评价非常高的王爽老师写的<汇编语言>(第三版),为了适应现在各个版本的windows操作系统,所以采用VMWare虚拟机来搭建纯DOS环境. 二. ...

  2. Linux下学习王爽老师的汇编语言

    坐起来非常容易,找到这条路确实非常曲折,为了后来的同志们不再纠结,特记录如下: 这几天看汇编语言时,很多人都推荐王爽老师的<汇编语言>,老师的书的确写的很好,但是讲的是ms的汇编,但是总不 ...

  3. 学_汇编语言_王爽版 要点采集笔记(未完待续&hellip;)

    第一章 基础知识 存储器(内存)存放CPU工作的指令和数据(CPU可以直接使用的信息在内存中存放):指令和数据都是二进制数没有任何区别,由CPU决定是数据还是指令 内存单元:存储器被分为若干个存储单元 ...

  4. 王爽汇编第十章,call和ret指令

    目录 王爽汇编第十章,call和ret指令 call和ret指令概述: ret和retf ret指令 retf指令 call 和 ret 的配合使用 call指令详解 call原理 call指令所有写 ...

  5. 王爽汇编第五章,[bx]和loop指令

    目录 王爽汇编第五章,[bx]和loop指令 [bx]和loop指令 例子: 王爽汇编第五章,[bx]和loop指令 [bx]和loop指令 [bx]之前我们介绍寄存器的时候,已经很详细的说明过了,b ...

  6. JAVA-集合作业-已知有十六支男子足球队参加2008 北京奥运会。写一个程序,把这16 支球队随机分为4 个组。采用List集合和随机数

    第二题 已知有十六支男子足球队参加2008 北京奥运会.写一个程序,把这16 支球队随机分为4 个组.采用List集合和随机数 2008 北京奥运会男足参赛国家: 科特迪瓦,阿根廷,澳大利亚,塞尔维亚 ...

  7. 项目 Web 的 NuGet 程序包还原失败: 找不到“1.0.0”版本的程序包“Microsoft.Net.Compilers”。。 0

    项目   Web 的 NuGet 程序包还原失败: 找不到“1.0.0”版本的程序包“Microsoft.Net.Compilers”.. 0 使用vs的NutGet包管理器时,另一台电脑从svn下载 ...

  8. 微信小程序商城开源项目,Weixin-App-Shop 1.0 版本正式发布!!!

    微信小程序商城开源项目,Weixin-App-Shop 1.0 版本正式发布 Weixin-App-Shop 是捷微团队开发的微信小程序商城开源项目,涵盖了微信商城的全部功能,能够快速发布简单易用的小 ...

  9. 《疯狂java-突破程序员基本功的16课 》笔记总结

    本人最近读完<疯狂java-突破程序员基本功的16课 >读完后,感觉对java基础又有了新的认识,在这里总结一下:一.数组与内存控制 1.1 数组初始化     java语言的数组是静态的 ...

随机推荐

  1. BZOJ2662[BeiJing wc2012]冻结——分层图最短路

    题目描述 “我要成为魔法少女!”     “那么,以灵魂为代价,你希望得到什么?” “我要将有关魔法和奇迹的一切,封印于卡片之中„„”     在这个愿望被实现以后的世界里,人们享受着魔法卡片(Spe ...

  2. BZOJ5251 八省联考2018劈配(网络流)

    劈配,匹配,网络流.那么考虑怎么跑网络流. 先看第一问.首先套路的建出超源超汇.不用想也知道导师向汇连容量为战队人数上限的边.特别地,给出局也建一个点,向汇连容量inf的边(似乎没有必要).对于一个新 ...

  3. IDEA 快捷键修改(长期更新)

    最近误操作,导致idea的快捷键没了. 痛定思痛,打算记录一下,以前修改过的key map 搜索一下就好了: 1  代码格式化 -- reformat code:Ctrl+Alt+L(如果按了没反应, ...

  4. 洛谷P3628 [APIO2010]特别行动队(动态规划,斜率优化,单调队列)

    洛谷题目传送门 安利蒟蒻斜率优化总结 由于人是每次都是连续一段一段地选,所以考虑直接对\(x\)记前缀和,设现在的\(x_i=\)原来的\(\sum\limits_{j=1}^ix_i\). 设\(f ...

  5. 如何用ip代替机器名访问sharepoint site

    1. iis里绑定ip 2. AAM里加一条ip的记录

  6. HTMLUnit web测试

    httpClient不能动态执行网页中的js,这样无法获取js生成的动态网页.htmlUnit是个解决方法. if you’re considering web application testing ...

  7. 压缩和解压缩文件tar, tar.gz and tar.bz2

    1, 对于tar.gz 压缩:tar -zcvf archive-name.tar.gz directory-name 解压:tar -zxvf prog-1-jan-2005.tar.gz -C / ...

  8. 自动生成Excel 报表工具类

    /** * 输出Excel文档 * * @param response * @param sheetName 文件名称 * @param firstCellTile 第一行的标题 * @param c ...

  9. laravel redis 删除指定前缀的 key

    // 前缀 $prefix = 'abc'; // 需要在前面连接上应用的缓存前缀 $keys = app('redis')->keys(config('cache.prefix') . $pr ...

  10. 盘点 php 里面那些冷门又实用的小技巧

    1.实用某个字段索引二维数组 取出一个数组的一个字段的值的数组,我们可以使用 array_column, 这个方法还有另外一个用法,如 array_column($array, null, 'key' ...