loop指令
- loop指令提供循环能力
- loop指令会判断cx寄存器的数值,不等于零转至标号处执行,等于零则向下执行
- loop指令处会执行(cx)=(cx)-1动作
loop指令样例
2^12示例
- 样例代码,这里ax+ax先做了一次才开始进入循环,也就是ax+ax总共是1+11次循环
- 调试流程,对ax赋初始值,给cx赋值循环变量,执行第一遍的ax=ax+ax
- 触发循环,观察cx的值不断递减,然后s标号处的ax+ax不断执行
- 观察最后cx等于0时的状态,查看是否还会执行ax+ax。cx等于0后循环出的汇编指令不会继续执行,而是直接运行loop下面的代码。
- 最后的ax的值是1000,最初的理解是800+800=1600,后来才回过神ax存储的数据全部都是16进制,8+8触发进位等于10,所以最终结果是1000。十六进制的1000等16^3=4096(十进制),16进制和8进制换算10进制有一种快捷方式,简单提供个公式,不具体讲原理了,需要的话网上可以搜索。1234(H)=(16^3)+(16^2)x2+16x3+4=4660。
- 这个例子中还有一个关键点,汇编代码中是一切皆内存地址
123x236示例
- 样例代码
- 右键进行调试,给ax赋值(7B)16x7+11=123,给cx赋值(EB)16x14+11=235,执行一次ax+123,然后进入235次循环ax+123
- 执行p命令直接跳过循环,观察最后的结果,ax=7164(H)=(16^3)x7+16^2+16x6+4=29028,最后可以用计算器算123x236也是等于29028
取内存数据运算
- 计算ffff:0006字节单元中数乘以3,结果存储在dx中。如果输入的idata开头是字母需要在数据前面加0,同时需要在后面加数据类型标识符H。如果输入的idata开头是数字,则没这些要求。
- 首先准备测试环境,为了测试充分计划向FFFF:0006中写入数据,然后再计算,测试很多次都失败了,使用dosbox汇编指令写也失败了
- 后来才想起来ffff段是特殊区域,该部分内存空间虽然被统一编制了(可以直接调用),但是该区域的内容是rom(只读内存,掉电不失),所以无法写入
- 修改原测试样例,由ffff:0006内存空间修改成2000:0006内存空间,整理的汇编代码如下。这里
- 使用debug进行跟踪验证,最终dl的值等于9c
- 提供一个变形样例,由于保存字段空间太小导致进位数据被丢弃,从而导致数据不准确
- 样例比较简单,先通过脑子计算一遍,然后再使用debug工具验证一遍
- 提供一个变形样例,由于由于dx数据清理不干净导致存储数据不准确。
- 再使用debug工具跟踪一遍
- 官方提供的样例