7.1 and 和 or 指令
二进制的and or 可以将某位归0或置1
7.2 关于ASCII码
7.3 以字符形式给出数据
data segment
db 'unIX' //相当于db 75H,6EH,49H,58H
db 'foRK' //相当于db 66H,6FH,52H,4BH
data ends
mov al,'a' //相当于mov al,61H
7.4 大小写转换问题
db 'BaSiC'
db 'iNfOrMaTiOn'
如何将第一个字符串转成大写,第二个小写?
我们将ASCII码拿出来对比一下:
大写 十六进制 二进制 小写 十六进制 二进制
A 41 010000001 a 61 01100001
B 42 010000010 b 62 01100010
C 43 010000011 c 63 01100011
..... ........
易知:小写字母比大写字母大20H,二进制中即第五位(位从0开始)为1和0
由于我们没有条件判断的指令来+或—20H来改变大小写,所以在这里用and 和 or指令改变二进制第六位数值来达到目的:
assume cs:code,ds:data
data segment
db 'BaSiC'
db 'iNfOrMaTiOn'
data ends
code segment
start:
mov ax,data
mov ds,ax
mov bx,0
mov cx,5
s:
mov al,ds:[bx]
and al,11011111B //第一个循环,前5个内存单元第五位归0 变大写
mov ds:[bx],al
inc bx
loop s
mov cx,11
s2:
mov al,ds:[bx]
or al,00100000B //第一个循环,后11个内存单元第五位置1 变小写
mov ds:[bx],al
inc bx
loop s2
mov ax,4c00h
int 21h
code ends
end start
7.5 [bx+idata]
用bx+idata来更灵活的指定偏移地址,也可以写成 idata[bx]很方便的用于表示数组(起始位置在idata,索引在bx)
7.6 用[bx+idata]处理数组
assume cs:code,ds:data //C语言
data segment
db 'BaSiC' //char a[5] = "BaSiC";
db 'MinIX' // char b[5] = "MinIX";
data ends
code segment
start:
mov ax,data
mov ds,ax
mov bx,0 // int i = 0;
mov cx,5
s: //do{
mov al,ds:0[bx]
and al,11011111B // a[bx] = a[bx] & 0xdf
mov ds:[bx],al
mov al,ds:5[bx]
or al,00100000B // b[bx] = b[bx] | 0x20
mov ds:5[bx],al
inc bx // i++;
loop s //while (i < 5)
mov ax,4c00h
int 21h
code ends
end start
7.7 SI 和 DI
SI 和 DI是与BX功能类似的寄存器,但是它们不能拆成两个8位寄存器
相同点: mov ax,[bx] mov ax,[si] mov ax,[di]
mov ax,[bx+idata] mov ax,[si+idata] mov ax,[di+idata]
练习:把 'welcome to masm!' 复制到它下面的内存单元中,利用si,di
assume cs:code,ds:data
data segment
db 'welcome to masm!'
db '................'
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov di,16 //si和di表示数组的2个index变量,放入循环
mov cx,16
s:
mov al,ds:[si]
mov ds:[di],al
inc si
inc di
loop s
mov ax,4c00h
int 21h
code ends
end start
简化程序;
assume cs:code,ds:data
data segment
db 'welcome to masm!'
db '................'
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,8 //利用idata[si]减少一个index参数
s:
mov ax,ds:[si]
mov ds:16[si],ax
add si,2
loop s
mov ax,4c00h
int 21h
code ends
end start
7.8 [bx+si] 和 [bx+di]
mov ax,[bx+si] = mov ax,[bx][si]
7.9 [bx+si+idata] 和 [bx+di+idata]
7.10 不同寻址方式的灵活应用
实例一: 把每个单词首字母大写
思路:定义一个变量用于循环每一字符串,另一个idata用于定位改字符串第3个位置(即该字符串第一个字母)
assume cs:code,ds:data
data segment //注意 每个字符串都是16位
db '1. file '
db '2. edit '
db '3. search '
db '4. view '
db '5. options '
db '6. help '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov bx,0
mov cx,6
s:
mov al,ds:[bx+3]
and al,11011111B
mov ds:[bx+3],al
add bx,16
loop s
mov ax,4c00h
int 21h
code ends
end start
实例二: 把单词变成大写
思路:显然是需要一个嵌套循环,如何处理cx被覆盖? 使用dx暂存外部循环的次数,在内层循环完成时,把dx返回给外层的cx
assume cs:code,ds:data
data segment
db 'ibm '
db 'dec '
db 'dos '
db 'vax '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov bx,0
mov cx,4
s0:
mov dx,cx
mov si,0
mov cx,3
s:
mov al,ds:[bx+si]
and al,11011111B
mov ds:[bx+si],al
inc si
loop s
add bx,16
mov cx,dx
loop s0
mov ax,4c00h
int 21h
code ends
end start
实例二中利用dx保存外部循环计数以便内部循环改变cx之后还能正常使用,但是我们的寄存器数量是很有限的,可以利用内存来存储变量
assume cs:code,ds:data
data segment
db 'ibm '
db 'dec '
db 'dos '
db 'vax '
dw 0 //定义字型内存单元 用于存储cx值
data ends
code segment
start:
mov ax,data
mov ds,ax
mov bx,0
mov cx,4
s0:
mov ds:[40H],cx
mov si,0
mov cx,3
s:
mov al,ds:[bx+si]
and al,11011111B
mov ds:[bx+si],al
inc si
loop s
add bx,16
mov cx,ds:[40H]
loop s0
mov ax,4c00h
int 21h
code ends
end start
利用内存的确可以保存变量值,但是这种做法还是比较不方便,实际上一般情况下 需要暂存数据的时候都用栈来保存.
assume cs:code,ds:data,ss:stack
data segment
db 'ibm '
db 'dec '
db 'dos '
db 'vax '
data ends
stack segment //定义一个16字节长度的栈
dw 0,0,0,0,0,0,0,0
stack ends
code segment
start:
mov ax,stack //栈指针初始化
mov ss,ax
mov sp,16
mov ax,data
mov ds,ax
mov bx,0
mov cx,4
s0:
push cx //cx值入栈
mov si,0
mov cx,3
s:
mov al,ds:[bx+si]
and al,11011111B
mov ds:[bx+si],al
inc si
loop s
add bx,16
pop cx //出栈放到cx中
loop s0
mov ax,4c00h
int 21h
code ends
end start
练习:把data段中每个字符串前4个字母改成大写
assume cs:code,ds:data,ss:stack
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
data segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
data ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
mov ds,ax
mov bx,0
mov cx,4
s0:
push cx
mov si,3
mov cx,4
s:
mov al,ds:[bx+si]
and al,11011111B
mov ds:[bx+si],al
inc si
loop s
pop cx
add bx,16
loop s0
mov ax,4c00h
int 21h
code ends
end start