从寄存器说起:
AX :一般用语临时存放数据,做数据中转。
CX:存放loop循环次数
CS:存放当前指令的段地址
IP:存放下一条指令的偏移地址,与CS联用
DS:存放数据段的段地址
SS:存放栈段的段地址。
SP:存放栈段的偏移地址,与SS联用,SS:SP始终指向栈顶,
BX:这个有点特殊,先从CPU寻址开始讲。一般CPU寻址都是: 段地址 x 16 + 偏移地址 = 实际物理地址。然而我们寻址 表达式就是 DS:AX,CS:IP,SS:SP等,也就是说指定其段地址,然而 汇编代码一般如下:
mov ax,0ffffh
mov ds,ax ;这里是因为段寄存器不可以直接从内存赋值
mov ax,ds:0fc ;这里的意思是,将 FFFF:FC这个地址里面的值赋值给 ax 寄存器。
如果是在Debug里面编程,那么上面的代码可以写成这个样子
mov ax,0ffffh
mov ds,ax
mov ax,[0fc] ; 注意,这里的[0fc]表示0fc是偏移量
但是,如果这些代码在MASM5.0编译器里面编译的话,就达不到理想效果,为什么呢,因为 MASM5.0编译器会把 [0fc]当成 0fc,那么。这行代码就成了 mov ax,0fc ;意思是将 0fc这个值传送到ax寄存器。然而最开始的代码意思是,将 FFFF:FC这个地址里面的值赋值给 ax 寄存器。这个就是DEBUG和MASM编译器的区别。现在,为了解决这个问题,我们用到了BX 如果用BX那么情况就不一样了。
mov ax,0ffffh
mov ds,ax
mov bx,0fc
mov ax,[bx]
我们用了两行代码来解决这个问题。首先把 0fc传送到 bx 然后 用 mov ax,[bx] ,把 FFFF:FC这个地址里面的值传送到 ax寄存器。达到了相同的目的,也就是说,在debug里面,如果用[idata]去指定偏移地址,是没问题的。但是在MASM5.0编译器里面,用[idata]那么,就直接变成了idata,要解决这个问题。就用 [bx] ,那么,不管是debug还是masm都可以达到目的。下面来总结下上面的话:
DEBUG mov ax,ds:[0fc] ;将 ds x 16 + 0fc里面的数据送到ax寄存器
DEBUG mov ax,[0fc] ;将 ds x 16 + 0fc里面的数据送到ax寄存器
MASM mov ax,ds:[0fc] ;将 ds x 16 + 0fc里面的数据送到ax寄存器
MASM mov ax,[0fc] ;将数据 0fc 送到ax寄存器
MASM mov ax,[bx] ;将 ds x 16 + bx 里面的数据送到ax寄存器
注:这个是BX寄存器特有的功能!
操作符:
mov : 传送数据的作用
mov ax,bx ; 寄存器 到 寄存器
mov ax,90h ; 数据 到 寄存器
mov ds,ax ; 数据寄存器 到 段寄存器
mov ds:[ax],bx ; 寄存器 到 内存单元
mov [bx],ax ; 寄存器 到 内存单元
mov [bx],ds:ax ; 内存单元 到 内存单元
add : 累加的作用
add ax,2 ; ax = ax + 2
add ax,ax ; ax = ax + ax
sub : 减法运算
sub ax,2 ; ax = ax - 2
sub ax,cx ; ax = ax -cx
inc : 操作数加 1
inc ax ; ax = ax +1
push : 入栈操作
push ax ;入栈操作 将 ax寄存器里面的内容放如栈顶 ,sp +2
push [bx] ;入栈操作 将 ds x 16 + bx 里面的内容放如栈顶,sp +2
push ds:0fc ;入栈操作 将 ds x 16 + 0fc里面的内容放如栈顶 ,sp +2
pop : 出栈操作
pop ax ; 将 栈顶数据传送到 ax , sp - 2
pop [bx] ; 将 栈顶数据传送到 ds x 16 + bx ,sp -2
pop ds:0fc ; 将 栈顶数据传送到 ds x 16 + 0fc ,sp -2
暂时就回忆到这里吧,要休息会儿,不是么,再写就吐血了!