1. 按位与/或指令:
1) and指令表示按位与,or指令表示按位或;
2) 两条指令的参数完全相同,都是将第一个参数和第二个参数进行按位运算,并将结果保存在第一个参数中;
3) 两个操作数的类型和前面讲过的mov指令差不多,并且这里先不提两个操作数都是内存单元的情况;
4) 操作数中不能有段寄存器,其余寄存器可以随便用,只要出现段寄存器就会报错!
5) 一般用途就是利用and将某些位置0,利用or将某些位置1;
2. 大小写转换问题:
1) 大小写字母之间的关系就是小写字母的ASCII码要比相应的大写字母要大20H;
2) 从二进制位上来看,所有小写字母的ASCII码的第三高位恒为1,而大写字母恒为0;
3) 因此可以通过按位与或置0置1的方式来转换大小写;
4) 示例:
assume cs:codesg, ds:datasg
datasg segment
db 'abcdefg'
db 'HIJKLMN'
datasg ends
codesg segment
start:
mov ax, datasg
mov ds, ax
mov bx, 0
mov al, 11011111B
mov cx, 7
lp1:
and [bx], al
inc bx
loop lp1
mov al, 00100000B
mov cx, 7
lp2:
or [bx], al
inc bx
loop lp2
mov ax, 4C00H
int 21H
codesg ends
end start
运行结果:
3. 乘法指令mul:
1) mul有两种类型,一种是两个8位相乘得到一个16位的结果,另一种是两个16位相乘得到一个32位的结果;
2) 双8位相乘:一个乘数默认放在al中,另一个乘数可以放在任意一个8位寄存器或者内存中,结果默认放在ax中;
3) 双16位相乘:一个乘数默认放在ax中,另一个乘数可以放在任意一个16位寄存器或者内存中,结果的高16位默认放在dx中,低16位默认放在ax中;
4) 使用格式:
; 8-bit mul 8-bit
mov al, XXX
mov 8-bit-register/memory, XXX
mul 8-bit-register/memory
; -> ax
; 16-bit mul 16-bit
mov ax, XXX
mov 16-bit-register/memory, XXX
mul 16-bit-register/memory
; -> [dx:ax]
5) 示例:100 × 10和100 × 10000:
assume cs:code
code segment
dd 0
start:
mov al, 100
mov ah, 10
mul ah
mov ax, 100
mov dx, 10000
mul dx
mov word ptr cs:[0], ax
mov word ptr cs:[2], dx
mov ax, 4C00H
int 21H
code ends
end start
运行结果:
*1. ax -> 03E8H
*2. 将结果保存在了代码段开头定义的数据区中,结果是000F4240H
4. 除法指令div:
1) 可以把div看做是mul的逆运算,因此div也有两种类型,分别对应着mul的两种类型;
2) 对应于字节型的mul,div的运行方式是,将被除数放在ax(mul的结果),除数放在8位寄存器或内存中,商默认存放在al中(mul的第一个默认乘数),而余数放在ah中;
3) 对应于字型的mul,被除数的低位放在ax中高位放在dx中(mul的结果),除数放在16位寄存器或内存中,商默认放在ax中(mul的第一个默认乘数),而余数放在dx中;
4) div使用方法,先对数据范围进行估计,然后执行上述步骤(即准备被除数和除数),最后直接执行"div 除数"指令即可,结果就保存在相应的寄存器中了;
5) 实例:1001 / 100和100001 / 100:
assume cs:code
code segment
mov ax, 1001
mov bl, 100
div bl
mov ax, 86A1H
mov dx, 1H
mov bx, 100
div bx
mov ax, 4C00H
int 21H
code ends
end
运行结果:
*1. 商是0AH,余数是1H
*2. 商是3E8H,余数是1H