通过一段代码发现 emu8086 和 DOSBox 的一点区别
来源:互联网 发布:xy苹果助手for mac 编辑:程序博客网 时间:2024/06/05 17:01
大家学习汇编语言的时候都需要一个能够编译执行的IDE。有的人用的win7或者更老的系统,就可以直接使用debug。而比较新的系统没有debug,就需要一个模拟器了,无论是DOSBox还是emu8086,都能满足我们学习的基本需求。
但是,这两种模拟器不是没有区别的,最近我就发现了一点小小的区别,希望能与大家分享一下。
1. 段内短转移
首先请看下面这段代码
assume cs:codesgcodesg segment start:mov ax, 0 mov bx, 0 jmp short s add ax, 1 s:inc axcodesg endsend start
这段代码很简单,我想我就不用详细介绍它的含义了。我们重点来看看这句:
jmp short s
这是一句段内短转移代码,它的作用是使得IP
从jmp
下一句的代码直接跳到s标号所指示的地址(如果还不理解的话可以看一看王爽《汇编语言(第3版)》9.3节对此的解释)。那么这句代码在机器语言中怎样表示呢?我们分别用emu8086和DOSBox来看一看。
- emu8086
这张图是这段代码在emu8086中编译的结果。首先来看右侧的伪代码,上述段内短转移语句被解释为
jmp 0Bh
。
其中0Bh
指的是最后那句
inc ax
的地址。也就是执行完上述段内短转移语句之后直接执行最后一句。
再看左侧的机器语言,这个语句被编译为EB 03
。其中EB
指的是jmp short
,而03
指的是从这个跳转语句的下一句跳到最后一句所需经过的位移。
- DOSBox
接下来看一下DOSBox的编译结果。基本内容和上面的一样,我就不多说了,大家自行体会。
刚才也说了,上面这段代码其实是jmp
的一种——段内短转移的对比效果,那么大家可以试一试另一种段内转移——段内近转移,最后得出的也会是一样的效果。
看到这里也许有人说,这没什么区别啊,你是不是在逗我们?别急,我们现在才讲了一个jmp short
,还有那么多其他类型的jmp
,他们都没有区别吗?接下来我们以jmp far ptr
(段间转移)为例来讲讲这两个模拟器的区别,前面的只是为了做铺垫,方便大家看出他们的异同。
2. 段间转移
又是一段代码:
assume cs:codesgcodesg segment start: mov ax, 0 mov bx, 0 jmp far ptr s db 256 dup (0) ; 这里只是为了创造一段位移而复制了256个内容为0的字节 s: add ax, 1 inc axcodesg endsend start
这是一句段间转移代码。作用与上面的段内短转移代码类似,不过顾名思义,这个可以跳转到任意地址。那么接下来我们看一下这段代码在两种模拟器中的编译结果。
- emu8086
这张图是这段代码在emu8086中编译的结果。首先来看右侧的伪代码,上述段内短转移语句被解释为
jmp 00109h
。
其中00109h
指的是倒数第二句
add ax, 1
的地址。也就是执行完上述段间转移语句之后直接执行倒数第二句。
再看左侧的机器语言,这个语句被编译为E9 0100
。其中E9
指的是jmp far ptr
,而0100
指的是从这个跳转语句的下一句跳到倒数第二句所需经过的位移。
看起来好像没有什么问题,但是根据jmp far ptr
语句的定义,它所跳转的地址应该是一个完整的地址,也就是段地址:偏移地址
,而这里的机器语言却给出了位移量,也就是说,它实质上进行的还是段内转移,而不是段间转移。
这个时候有人就要问了,可是你只进行了100h
的位移啊,当然是段内转移了。并不是这样,因为无论位移是多少,只要我用的是段间转移,那就必须是一个完整的地址,不能是位移量。即使就像这种说法说的那样,小于一个段的长度会变为段间转移,那大家可以试一试大于一个段的长度,比如进行2333h
的位移,大家会发现机器语言给出的还是位移量。
这个现象我也无法解释,只能暂时说emu8086似乎并不能正确模拟段间转移。至于DOSBox是可以的。
- DOSBox
这是DOSBox的编译结果,可以看到:
jmp far ptr s
被解释为如下伪代码:
jmp 076A:010B
其中076A:010B
指的是要跳转到的段间地址
进而被编译为如下的机器语言:
EA 0B016A07
其中EA
指的是jmp far ptr
,0B016A07
指的是076A:010B
。
我们显然可以看出,对于段间转移,DOSBox的机器代码和emu8086有很大不同,DOSBox能够进行段间转移,而emu8086似乎并不具备这个功能。
3. 总结
通过以上对比我们可以看出,有些模拟器的功能并不健全,比如emu8086就不能进行段间转移,这个时候DOSBox就发挥作用了,虽然它很难使用,但是起码目前来看完全能够支持我们编写的代码,所以不要因为它又丑又难用就放弃它哦。
- 通过一段代码发现 emu8086 和 DOSBox 的一点区别
- 从一段代码来看指针和数组名的区别
- 一段代码让你理解set和list的区别
- 一段代码解释retain,strong和copy的区别
- DOSBox下编译和运行NASM代码
- Emu8086下载和注册
- 关于DataGrid 和DataSet的一点发现
- replace和replaceAll的一点发现
- 一段代码,const,readonly,static的区别
- DosBox的基本设置和安装
- win7 64位通过dosbox使用debug的方法
- 在dreamweaver中编写asp代码的一点小发现
- 看chromium代码发现一点有趣的东西
- 更新一点,查寻任意一段中子串的最大和
- axmapcontrol的一点发现
- 很详细的一段关于scanf()和getchar()区别的代码
- 通过按钮复制一段代码
- emu8086不支持的x86语法
- Excel导入导出
- 软考视频总结
- 关于Keil Uv4工具绿化版拷贝到另一台电脑时编译失败显示版本过期问题的解决
- String.substr()和String.substring()
- 写给人类的机器学习 2.2 监督学习 II
- 通过一段代码发现 emu8086 和 DOSBox 的一点区别
- 字母排序(最长递增子串)
- hdu-154-Tunnel Warfare(线段树,区间)
- BZOJ 4236 JOIOJI
- <并查集+脑洞>codevs 1995 黑魔法师之门
- 复变函数ch3.复变函数的积分
- PTA:一元多项式的加乘运算
- 新的启程------加油
- Linux 磁盘原理与管理 (分区 挂载)