1.and 和 or 指令
and ->用来做逻辑与运算
例如:
mov ax,0011B
and ax,0001B
结果:ax 中的值为0001B
or ->逻辑或运算
指令:
mov ax,0011B
or ax,1100B
结果:1111B
2.字符型数据
伪指令db(define byte)可用来定义字节型数据;
例如:
db 5
可以使用伪指令db来定义字符型数据;
格式为:db '字符串'
db 'HelloWorld'
db 'a'
用单引号括起来'......'的方式表示数据以字符的方式给出,编译器会将其中的字符转换成它们对应的ASCII码;
例如:db 'u' 相当于 db 75H;
1)关于大小写转换
通过查ASCII表可知:大写字符+20H=小写字符;
例如:将hello 转换成HELLO
assume cs:code,ds:data
data segment
db 'HELLO' ;定义字符串大写的HELLO
data ends
code segment
start: mov ax,data ;程序入口
mov ds,ax ;将段寄存器ds指向数据段data
mov bx,0 ;偏移地址设为0
mov cx,5 ;设置循环次数
s: add byte ptr [bx],20h;转换成大写,根据ascii码:'A'+20h='a',byte ptr 表示传送的时字符型数据,word ptr表示字型数据
inc bx ;偏移地址自增1
loop s ;从标记s处循环
mov ax,4c00h;程序返回
int 21h
code ends
end start
也可以利用and和or来转换大小写:
例如:a 和 A之间的转换
ascii码:
a ->01100001
A ->01000001
可以看出第六位的0和1决定了a的大小写;
利用and和or可以改变某一位的值;
a转A:
mov al,01100001b
and al,11011111b
A转a:
mov al,01000001b
or al,00100000b
3.[bx+idata]
[bx]可以用来表示内存单元的偏移地址;
[bx+idata]表示偏移地址为bx中的值+idata的值;
例如:
mov ax,[bx+5]
其它表示方式:
mov ax,0[bx] ;相当于 mov ax,[0+bx]
mov ax,5[bx] ;相当于 mov ax,[5+bx]
4.SI和DI
si和di寄存器和bx寄存器的用法相似,可用来表示偏移地址;
但si和di不能被拆分成两个8位寄存器来使用;
例如:下面的三条指令功能相同
mov ax,[bx+123]
mov ax,[si+123]
mov ax,[di+123]
也可以将si和di与bx混合使用:[bx+si]、[bx+di]
mov ax,[bx+si]
mov ax,[bx+di]
si和di与bx以及idata混用:[bx+si+idata]、[bx+di+idata]
mov ax,[bx+si+6]
该指令的其它表示方式:
mov ax,[bx][si].6
mov ax,6[bx][si]
mov ax,[bx].6[si]
5.不同寻址方式的灵活运用
比如:某个程序需要进行其嵌套循环时;
因为循环需要用到cx寄存器;
而内层循环会改变cx的值,而影响外层循环;
可以考虑将cx的值在进入内层循环前保持起来,在内存循环结束后,再重新赋给cx;
可以用另一个寄存器,比如dx来保存;
但是可能程序太复杂,而寄存器数量有限,比如dx被占用了;
可以用将cx的值保持在内存中,而不是用寄存器来保存;
具体做法是:在数据段中用dw定义一个字,用来保存cx的值;
这样做也有个问题:当需要保存多个数据时,必须记住数据保存到了哪个空间,容易混淆;
为了让程序更加清晰:一般来说在需要暂存数据时,我们都应该使用栈;
例如:分别将下面四个字符串的前三个字母转为大写
assume cs:code,ds:data,ss:stack
data segment
db 'one3456789abcde'
db 'two3456789abcde'
db 'thr3456789abcde'
db 'fou3456789abcde'
data ends
stack segment
dw '0,0,0,0,0,0,0,0' ;定义一个16个字节的栈段
segment ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov ax,stack
mov ss,ax
mov sp,16 ;ss:sp指向栈顶
mov cx,4
s:push cx ;将外层cx的值入栈
mov si,0
mov cx,3
s0:mov al,[bx+si]
and al,11011111b
mov [bx+si],al
inc si
loop s0 ;内层循环
add bx,16
pop cx ;从栈中弹出cx的值,恢复外层循环计数
loop s ;外层循环
mov ax,4c00h
int 21h
code ends
end start