汇编实验三

  这次实验的主要内容是了解汇编程序的从编程到运行的整个流程。整个流程分为:编程->编译->链接->运行(测试)。当中我们会用到:文本编辑器,masm(编译用的),link(链接用的),debug(跟踪调试用)。

  首先我们先编写一个汇编程序。打开记事本写入如下指令,保存为t1.txt。如图。

   

   保存如下图。(Macos 下默认的文本文件格式为 RTF,Windows 下为TXT。)

    

  由于 macOS的文本编辑器编辑完会在文件前自动加上一些格式设置(可能是我之前设置过文本编辑器的原因),会导致编译失败。但是,在文本编辑器中又看不到,所以我们需要通过控制台中将这些设置删除。(win 10 下没有这个问题。早知道这样我就直接用命令行写了。给上一张写完的 t1  在控制台中的图。

  

 

 

  将除了之前写入的代码的所有字符全部去掉。使用 cd 命令转到源文件所在的文件夹,然后用 nano 或者 vim 打开进行编辑。如图。

  

  之后如图。nano 的操作比较简单,使用上下左右和退格键即可,必要时可以按 F1查看帮助。

  

  清除完之后,按 Ctrl+X,然后输入 y,然后回车保存退出。(给出清理后的源文件截图)

  

   PS:有人可能会说,为什么不改后缀?其实改不改没有影响,大家可以自己试一下。 

  

 

  接下来的操作我觉得是比较重要的吧。我周围的同学对于工作目录不是特别了解。这个原因造成了他们编译时找不到源文件从而报错。在此和大家说一下工作目录的问题。

  在 dosbox 运行时,我们会有一个 mount 操作(可能有人说没有,因为在开始使用的时候,你配置过了环境,让 dosbox 启动时自动帮你完成了。),如下图。

  

  这个语句是什么意思呢?这个语句实际上完成的是 dosbox 中文件(文件夹)到实际操作系统中文件(文件夹)的一个映射。dosbox,它是在我们的电脑上模拟了 dos 环境,那么,我们要在其中使用一些文件时,如何让它知道文件在哪呢,那这个映射就发挥作用了。(可以理解成给它起了个别名)

  那么它和编译失败有什么关系呢?你在实际操作系统中写的源文件在哪(上面的源文件我保存在了桌面,你想必也知道自己保存在了哪),而 dos它不知道。在上图的 dos 环境下,系统只知道,Z 盘(dos 所在的盘,可以说是系统盘)和我 mount (挂载)上去的C 盘。然而这两个目录下并没有源文件,必然编译失败。所以我们要做的就是让他知道这个文件在哪。

  怎么让它知道?有两个办法:

  第一个,把这个文件直接丢到之前 mount 的那个文件夹里(图中为 masm ,路径为 /users/willeasun/masm/,每个人都不同。)

  第二个,把源文件或者源文件所在的文件夹也 mount 上去,然后把路径给 masm 和 link 以及 debug 即可。

  下面演示一下两个方法。如图。

  第一种比较简单,丢进mount 好的文件夹,然后编译就完事了。

  

  

   输入 masm t1.rtf ,然后回车。(想偷懒的可以打完 mount t1 然后按 tab 键,由系统自动补全。只要后缀系统能够识别,就可以用)

  

  第二种,首先用 mount 命令挂载源文件或者源文件所在的文件夹。

  

  然后用 masm 进行编译。 输入 masm o:\t1.rtf ,回车。

  

  当然你也可以把当前的目录切换到刚刚 mount 的那个盘(图中的 O 盘),然后输入 c:\masm t1.rtf , 然后回车。

  注:这里要注意,编译生成的目标文件保存在你的当前工作目录。我当前在 O 盘就保存在 O 盘,在 C 盘就保存在 C 盘。

  

  不管你使用哪种方法,你需要知道你要编译或者链接又或者调试的文件在哪,然后给出对应的路径即可。

 

 

  接下来是链接,由此开始,我只演示一种方法。

  输入 link t1.obj,然后回车。

  

  没有报错,只有警告。此时当前目录下会生成一个exe文件,名字如果你没改,那就是t1,如果你在编译或者链接的时候更改过,那就是你更改的名字。

  

  我们来运行一下这个程序。

  输入 t1.exe 。

  

  屏幕上出现了 36 。

 

  我们代码中有3和6 ,我们更改了再看看。这次改为4 和 8 。

  

  再次编译,链接,运行,这次的结果如图。

  

 

  接下来,我们用 debug 调试它。输入 debug t1.exe ,然后回车。下面会出现一个熟悉的小短线,说明我们成功进入了 debug。

  

  

  然后我们来单步调试它。看看ds 和cs 之间有没有什么关系。

  

  他们两之间满足:(cs)=(ds)+10H 。

 

  我们看看去看看075a 有些什么东西。

   

  开头有个 int 20 ,百度了一下,是程序中断的意思。应该是

  

  接下来,我们反汇编代码,然后单步调试它。反汇编出来的就是我们卸载 code segment 里的代码。由此看出,源文件里起作用的只有 segment 里的语句。

  

  

  我们来单步调试它。 

  

  

  

  从图中可以看到,每次执行到 int 21 就会输出。这应该就是8086 的输出指令吧。每当你要输出,就把 ah 改成02,把你要输出的数放在 dl 上并加上30 H,然后执行 int 21,就会把你要输出的数值输出到屏幕。

 

 

 

  第二个实验

  也是将给定代码编译运行,只是这次用寄存器代替了数据段的偏移地址。

  第一步肯定是敲代码,这次我直接在命令行里敲了,避免之前的问题。

  

  开始我以为代码都是对的,经人提醒(可以看评论),我才知道老师有说是错的,然后知道哪里有问题。错误在于:第7和第10行只给出了数据段偏移地址并没有指定数据长度。现在贴出正确代码:

  

 

  保存然后一样的了链接,运行。

  

  图上出现了一个红色的36。

  

  我们把代码当中的0433h改成0432h,0436h 改成0439h 再试试。这次数字变成了红色的29。

  

  我们再把0433h 改成 0333h ,0436h 改成 0336h 。再看有什么变化。得到的是一个淡绿色的36。

  

  

  在实验一中我们也有个类似的实验,只是那个更改的是 b8100h,这次我们改的 b8000h ,并且,那次,我们是一个字节一个字节的写入的数据,而这次我们是用 mov 语句进行的赋值。我大胆的猜测:b8000h 开始的地址空间就是我们屏幕所在的地址空间。

  而对比这两个实验,我们可以发现:输出数值到屏幕可以调用输出指令去实现,也可以直接修改屏幕所在的内存空间。

 

 

  总结与体会:

  通过这次实验,我熟悉了汇编源文件到可执行文件的整个过程,了解了输出指令的使用。

 

转载于:https://www.cnblogs.com/Willeasun/p/9966818.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值