汇编语言第七章&实验六
7.1 and和or指令
and指令,逻辑与指令,按位进行与运算
mov al,01100011B
and al,00111011B
执行后al=00100011B,通过该指令可将操作对象的相应位设为0,其他位不变
or指令,逻辑或指令,按位进行或运算
mov al,01100011B
or al,00111011B
执行后al=01111011B ,通过该指令可将操作对象的相应位设为1,其他位不变
7.2 关于ASCII码
我们把信息存储在计算机中,就要对其进行编码,转化为二进制信息,而计算机将存储的信息显示给我们看,就要进行解码,ASCII码就是一种编码方案
在编辑文本时按下a键,这个按键的信息传入计算机,计算机编码后转化为61H存储在内存中,文本编辑软件从内存中取出61H,将其送到显卡上的显存中,工作在文本模式下的显卡,用ASCII码的规则解释显存中的内容,61H被当作字符a,显卡驱动显示器将字符a的图像画在屏幕上
7.3 以字符形式给出的数据
在汇编程序中,用’……'的方式指明数据是以字符的形式给出的,编译器将它们转化为对应的ASCII码
assume cs:code,ds:date
data segment
db 'unIX'
db 'foRK'
data ends
code segment
start: mov al,'a'
mov bl,'b'
mov ax,4c00h
int 21h
code ends
end start
db ‘unIX’相当于’db 75H,6EH,49H,58H’
mov al,'a’相当于mov al,61H
7.4 大小写转换的问题
将datasg中的第一个字符串转化为大写,第二个字符串转化为小写
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-awc0M48Y-1583139213436)(C:\Users\田明浩\AppData\Roaming\Typora\typora-user-images\image-20200302130808763.png)]
第一种方法,观察到小写字母的ASCII码值比对应的大写字母ASCII码值大20H,但是由于字符串中既有大写又有小写,需要进行判断是否为大写或者小写,但目前还没学过使用汇编的判断语句
第二种方法,从ASCII码的二进制形式来看,除第5位(从0开始计数)外,其他各位都一样,所以对于一个字母,不管大写小写,将第5位置置零即可
assume cs:codesg,ds:datasg
datasg segment
db 'BaSiC'
db 'iNdOrMaTiOn'
datasg ends
codesg sgement
start: mov ax,datasg
mov ds,ax
mov bx,0
mov cx,0
s:mov al,[bx]
and al,11011111B
mov [bx],al
inc bx
loop s
mov bx,5
mov cx,11
s0:mov al,[bx]
or al,00100000B
mov [bx],al
inc bx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
7.5 [bx+idata]
可以用[bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata
以下指令等价
mov ax,[bx+200]
mov ax.[200+bx]
mov ax,200[bx]
mov ax,[bx].200
7.6 用[bx+idata]的方式进行数组的处理
在codesg中填写代码,将datasg中定义的第一个字符串转化为大写,第二个字符串转化为小写
原来的方法需要两个循环,但在同一个循环里也可以完成
assume cs:code,ds:datasg
datasg segment
db 'BaSiC'
db 'MinIX'
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov bx,0
mov cx,5
s:mov al,[bx]
and al,11011111B
mov [bx],al
mov al,[5+bx]
or al,00100000B
mov [5+bx],al
inc bx
loop s
mov ax,4c00H
int 21H
codesg ends
end
比较c语言和汇编语言
C:a[i],b[i]
汇编:0[bx],5[bx]
7.7 SI和DI
si和di是8086CPU中和bx功能相近的寄存器,si和di不能分成两个8位寄存器来使用
下面3组指令功能相同
mov bx,0
mov ax,[bx]
mov si,0
mov ax,[si]
mov di,0
mov ax,[di]
用si和di实现将字符串’welcome to masm!'复制到它后面的数据区中
assume cs:codesg,ds:datasg
datasg segment
db 'welcome to masm!'
db '................'
datasg ends
codesg sgement
start: mov ax,datasg
mov ds,ax
mov si,0
mov cx,8
s:mov ax,0[si]
mov 16[si],ax
add si,2
loops
mov ax,4c00h
int 21h
codesg ends
end start
7.8 [bx+si]和[bx_di]
[bx+di]即偏移地址为(bx)+(si)
以下指令等价
mov ax,[bx+si]
mov ax,[bx][si]
7,9 [bx+si+idata]和[bx+di+idata]
[bx+si+idata]即(bx)+(si)+idata
常用格式
mov ax,[bx+si+200]
mov ax,[bx+200+si]
mov ax,[200+bx+si]
mov ax,200[bx][si]
mov ax,[bx].200[si]
mov ax,[bx][si].200
7.10 不同寻址方式的灵活应用
将datasg段中每个单词的头一个字母改为大写字母
assume cs:codesg,ds:datasg
datasg segment
db '1. file ' ;每个字符串长度为16个字节,因为连续存放
db '2. edit ' ;加空格保证两个字符串不在同一个段中
db '3. search '
db '4 .view '
db '5. options '
db '6. help '
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov bx,0
mov cx,6
s:mov al,[bx+3]
and al,11011111B
mov [bx+3],al
add bx,16
loops
mov ax,4c00h
int 21h
codesg ends
end start
将datasg段中每个单词改为大写字母,这样就要用到二重循环,但是两个循环都要用到cx,所以需要暂存外层循环cx的值,可以使用寄存器暂存,但是一般来说,在需要暂存数据的时候,我们都应该使用栈
assume cs:codesg,ds:datasg,ss:stacksg
datasg segment
db 'ibm '
db 'dec '
db 'dos '
db 'vax '
datasg ends
stacksg segment
dw 0,0,0,0,0,0,0,0 ;定义一共栈段,容量为16个字节
stacksg ends
codesg segment
start: mov ax,stacksg
mov ss,ax
mov sp,16
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,4
s0:push cx ;外层循环的cx压栈
mov si,0
mov cx,3
s:mov al,[bx+si]
and al,11011111B
mov [bx+si],al
inc si
loops
add bx,16
pop cx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
实验六
编程,将datasg段中每个单词的前4个字母改为大写字母
assume cs:codesg,ss:stacksg,ds:datasg
stacksg segment
dw 0,0,0,0,0,0,0,0
stacksg ends
datasg segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
datasg ends
codesg segment
start: mov ax,stacksg
mov ss,ax
mov sp,16
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,4
s0:push cx
mov si,3
mov cx,4
s0:push cx
mov si,3
mov cx,4
s:mov al,[bx+si]
and al,11011111B
mov [bx+si],al
inc si
loop s
pop cx
add bx,16
loop s0
mov ax,4c00h
int 21h
codesg ends
end start