[bx]是什么
[bx]这个表达方式和[0]很像,他们俩的功能也很像。之前就提到了,[0]表示一个内存单元,他的偏移地址是0。从这边我们可以引出内存单元的定义:要有内存单元的地址,要有内存单元的长度(类型,例如字单元和字节单元)
那么[bx]其实也和[0]差不多,其中0代表偏移地址是0,那么[dx]中的dx就是代表他的偏移地址在dx中,所以按照内存单元的定义来说,[dx]也表示一个内存单元,这个内存单元的偏移地址在bx中。
这边要区分开bx和[bx],bx是类似寄存器的东西,他是有地址的,这个地址可以放数据的,[bx]则表示一个内存单元,有地址有长度
如果还是不太理解可以看一下书里面97页的实验。
loop是什么
从字面上看loop就是循环的意思,执行loop指令的时候会执行两步操作,先会把cx中存放的内容减一,再判断cx的值,如果不为零则继续执行标号处的指令,如果为零则跳出循环继续执行标号处下一条的指令。
从这两步操作我们可以知道,cx中存放的内容是loop循环的次数,所以在使用loop循环之前,我们要先给cx赋值需要的循环次数。
至于标号,我们之前也没碰到过,其实就是在指令前面加一个字符:用来表示标号,类似这样子
这边就给cx放入内容11,标号s,之后执行loop s就会重复11次标号s的指令。
储存循环次数的寄存器有三个从小到大依次是c1,cx,ecx,分别是二进制的8、16、32位。
debug和masm汇编编译器对指令的不同处理
之前我们大多实在debug的环境下也就是dosbox提供的dos环境去调试汇编语言,但并不是所有的调试器编译器对汇编语言的解释都是一样的,就像这个小标题一样。
这边就写一点点:书本中举例的是 mov ax,[0] 这条指令。对于debug调试器来说就不多说了,和前面说到的都一样,但是对于masm编译器来说这条指令中的[0]就会被解释成0,我们知道[0]代表的是内存单元,但是对于0masm就会有独特的逻辑去执行。
这边只是那这两个去举个例子;到这边可能会想,那怎么让汇编语言具有较好的兼容性?可以去搜看看,这边不多写。
对于循环的定义方式
上面我们利用标号s来作为循环的名称,s:后面的指令则是要循环的指令。这边要去查循环的指令不止是单单s:后面那句,也可能是一段,循环语句结束的标识是loop+标号。例如
想这种的就说明一整段都是循环语句
像这种的就是只有标号后面那一句。
关于类似c1,cx,ecx三个寄存器的关系
这三个寄存器是类似包含的关系,首先这三个寄存器依次可以存放8,16,32位二进制数,对应的十进制分别是255,65535,4294967295,其中c1同时是cx和ecx的低八位,cx是ecx的低八位,我们可以通过给这三个赋值去控制循环的次数。因为他们有类似包含的关系,所有当他们三个寄存器肯定是同时有数据或者无数据的,所有也不存在冲突的现象。
当然其他的寄存器类似ax,bx也同样是这种包含的结构。
使用指令对于操作数据长度和寄存器大小的要求
类似这段指令
粗看一边可能会有疑问为什么不直接把ds:bx的数据放入ax,而是放入a1。
这是因为操作的数据长度和寄存器的大小要一致,首先我们是依次把ffff:0~ffff:b地址内的数据给放入寄存器中,x86 架构的内存基本单位是以八位二进制数为最小内存和访问单元的,所以ffff:1内的数据大小最大也是一个字节也就是八位二进制数,所以要用也是1个字节的寄存器a1来接收这个数据。
段前缀
段前缀是用于强制指定内存访问所用段寄存器的指令前缀,其核心功能是打破 CPU 对段寄存器的默认选择,灵活访问不同段中的内存数据,是 x86 分段内存模型中实现灵活内存访问的重要机制。
其代码结构类似
mov ax, cs:[si]
其中cs就是段前缀。