bx 寄存器和 loop 循环的学习小结🛰️
符号和常量
描述性符号"( )"
使用"( )"来表示一个寄存器或一个单元中的内容
“( )”中的元素有3种类型
- 寄存器名
- 段寄存器名
- 内存单元的一个物理地址(一个20位的数据)
例如:(ax)、(20002h)、((ds)*16+(bx))
idata 常量
就是表示一个常量,没啥好解释的。
例如:
1 | mov ax,[idata] 就代表 mov ax,[1]、mov ax,[2] 等 |
[BX]
什么是[bx]
bx是一个通用寄存器的代号,当 bx 变成 [bx] 时,bx 的值就不单单代表着数值,它还表示着偏移地址。
如何运作
举个例子
- mov ax,[bx]
功能:bx中所存放的数据作为一个偏移地址,然后再结合 ds 中段地址的数据计算出物理地址
1 | 物理地址=(ds)*16+bx |
然后将该物理地址中的数据送入 ax 中。
Loop
什么是 Loop
loop 中文意思是:循环。
作用也就很明显了,它就相当于我们最常接触的 while 和 for,循环的一个关键是循环的次数,而在汇编语言中 loop 所循环的次数是由 cx 所决定的。
格式以及运作原理
格式如下:
1 | ... |
- 标号 s 要放在 loop 指令之前
- 循环执行的程序段放在标号和 loop 指令之间
运作原理:
当 CPU 执行 loop命令时会执行一下两个步骤:
- (cx)=(cx)-1
- 判断 cx 的值是否为0,如果不为0,则跳转至 s 处继续执行代码;如果为零,那就继续执行下一条指令
两者的联合使用
当我们需要对连续性变化的内存地址进行重复性的操作时,如果我们不适用循环,那我们的源码会变得十分冗长,且有很多的重复性语句。
例如:计算 ffff:0~ffff:b 单元内数据的和,结果储存在 dx 中
首先我们最应该考虑的是数据是否会溢出,数据类型是不是匹配等问题。很显然,溢出的问题是不存在的,但是将 ffff:0 中的数据直接放入 bx 中是不可取的,因为前者的数据是8位,而后者的数据是16位。
通过如下步骤解决问题
1 | mov al,ds:[0] //将目标数据放入低位的 ax 寄存器中 |
不利用循环的源码
1 | assume cs:code |
该程序中间的实现功能的主要部分大多都是相似的,变化的不过时偏移地址的值,因此我们在循环中改变偏移地址的值即可。
使用循环的源码
1 | assume cs:code |
本文作者:GhDemi
本文链接: https://ghdemi.github.io/2022/05/24/BX%E5%92%8CLoop/
文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。