1、定义多个段

  dw:数据类型,就是define word   字型数据(16位)

  db:字节型数据(8位)

  dd:双字型数据(32位)

  我们把数据,代码,栈都放入同一个段中,显得程序很是混乱;

  8086一个段的空间大小为2^16(64K);当我们所需的空间大小大于64KB时,将不能执行;

  此时,解决方案:

  (1)、定义多个段,将不同的数据、代码、栈放到不同的段中,这就是采用了封装的思想。

  (2)、我们通常在源程序中为这三个段起了具有含义的名称,存放数据的段叫"data",存放代码的段叫"code",栈空间叫"stack";

  (3)、assume cs:code, ds:data, ss:stack,将寄存器与这些段相连接了;此时,cs指向code段,ds指向data段,ss指向stack段;

  (4)、end start说明了程序的入口,CPU的CS:IP被设置指向这个入口,

  (5)、在将不同的段寄存器赋其相应的地址即可(中间通过通用寄存器作为桥梁);


2、简单逻辑指令

  (1)、and指令:逻辑与指令,按位进行与运算;or指令:逻辑或指令,按位进行或运算;

  (2)、ASCII码:对字符的编号;

  大小写的转换问题:

  一个字母,不管原先是大写还是小写字母:对其二进制的第5位设置为0,就变成大写字母;将它的第5位设置为1,它将变成小写字母;


3、SI和DI

  SI和DI是8086CPU中和bx功能相近的寄存器(表征偏移地址),但是SI和DI不能够分成2个8位寄存器来使用;段地址都存放在ds寄存器中;

  SI:一般放的是原数据的...;

  DI:一般放的是目的数据的...;

  SI、DI和bx关系比较好,可以互换、组合使用;


3、寻址方式

  (1)、[bx+idata]:表示一个内存单元,它的偏移地址为(bx)+idata;(bx中的值加上idata)

  [bx+si/di]、[bx+si/di+idata]

  有了[bx+idata]这种表示内存单元的方法,现在就可以使用数组了;

  汇编语言的定位方式:0[bx], 5[bx]

  (2)、假如我们在循环中需要使用的保存的数据很多,而寄存器数量又不够时,此时怎么办?

  应该把需要暂存的数据放到内存单元中去,需要使用的时候,再从内存单元中恢复,我们就得开辟一段内存空间;


4、寄存器

  (1)、reg:寄存器; sreg:段寄存器

  reg:ax、bx、cx、dx、ah、al、bh、bl、ch、cl、dh、dl、sp、bp、si、di;

  sreg:cs、ds、ss、es;

  (2)、8086CPU中只有(bx、bp、si、di)可以放到[]中来进行内存单元的寻址.

  (3)、在[]中使用寄存器bp,没有给出段地址的话,段地址就默认在ss中,bp就相当于sp;bp就是用来给sp帮忙的;

  (4)、指令在执行前,所要处理的数据可以在三个位置:CPU内部、内存、端口;


5、2个问题

  (1)、汇编语言中用三个概念来表达数据的位置:

  i>、立即数(idata).ii>、寄存器.iii>、段地址和偏移地址;

  (2)、指令要处理的数据有多长?

  8086CPU的指令,可以处理两种尺寸的数据,byte和word,所以在机器指令中要指明,指令进行的是字操作还是字节操作;

  i>、通过寄存器名指明要处理的数据的尺寸;

  ii>、在没有寄存器名存在的情况下,用操作符X ptr指明内存单元的长度,X在汇编指令中可以为word或byte;  例:mov word ptr ds:[0], 1 表明了处理的是一个字单元;

  iii>、在没有寄存器参与的内存单元访问指令中,用word ptr或byte ptr显性的指明所需访问的内存单元长度是很有必要的。否则,CPU无法得知所要访问的单元是字单元还是字节单元;

  iv>、有些指令默认了访问的是字单元还是字节单元:比如,push[1000H]就不用指明访问的是字单元还是字节单元,因为push指令只能对字操作;


6、寻址方式

  一般来说,我们可以用[bx+idata+si]方式来访问结构体中的数据;

  用bx定位整个结构体,用idata定位结构体中的某一个数据项,用si定位数组项中的每个元素;

  汇编语言的做法:bx.10h[si];


7、div指令

  div是除法指令,使用div作除法的时候,被除数默认放在AX或DX和AX中;

  除数为16位的时候,被除数此时为32位(DX+AX);此时,dx放的是高16位值,ax放的是低16位值;


8、dup

  dup是一个操作符,和db、dw、dd等数据定义伪指令配合使用,用来进行数据的重复;

  db 3 dup(0):定义了3个字节,他们的值都是0;

  db 3 dup('abc', 'ABC'):定义了18个字节;'abcABCabcABCabcABC'

  dup的使用格式:

  (1)、db 重复的次数 dup(重复的字节型数据)

  (2)、dw 重复的次数 dup(重复的字型数据)

  (1)、dd 重复的次数 dup(重复的双字数据)

  在定义数据方面特别的有用,节省了代码的大量复杂度;

  定义一个容量为200个字节的栈段,使用dup定义如下:

stack segment
  db 200 dup(0)
stack ends


9、转移指令

  (1)、8086CPU的转移指令分为:无条件转移(jmp)、条件转移指令、循环指令(loop)、过程、中断;

  offset:取得标号的偏移地址;

  (2)、jmp指令:jmp为无条件转移,可以修改IP,也可以同时修改CS和IP;

  jmp指令要给出2种信息:转移的目的地址,转移的距离(段间转移、段内短转移、段内近转移);

  jmp short 标号--->段内短转移,对IP的修改范围(-128--127);

  jmp far ptr 标号--->段间转移,远转移;

  (3)、jcxz:有条件转移指令,所有的有条件转移指令都是短转移,对IP的修改范围都为-128--127;

  指令格式:jcxz 标号;当(cx)中的内容为0时,才发生跳转,否则不进行跳转,程序向下执行;

if((cx) == 0)      //功能等价于jcxz 标号;
  jmp short 标号;

  (4)、loop指令-->循环指令,所有的循环指令都是短转移,

  指令格式:loop 标号;((cx)) = (cx) - 1,如果(cx)不等于0,转移到标号处执行.