第七章 灵活运用寻址方式(si/di和内嵌套循环)——所有的习题练习
2012-05-29 01:47
239 查看
1、问题:将下面小写字母变为大写,大写变为小写?
//7_1.asm(正确代码)
assume cs:code,ds:data
data segment
db 'abcde'
db 'ADCDEFGHIJ'
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 //(1.为什么不能直接,and ds:[bx],11011111B 呢?这次不是可以确定了要操作对象是一个字节吗?)——书上的例子只有寄存器与数据操作这一种情况,and al,11011111B (and/or用的是寄存器与数据打交道.)
mov ds:[bx],al //(绿色表示没有解决的问题,或存疑的地方?有待以后解决之!)
inc bx
loop s
mov cx,10
s1:
mov al,ds:[bx]
or al,00100000B
mov ds:[bx],al
inc bx
loop s1
mov ax,4c00h
int 21
code ends
end start
//7_1_1.asm(为了验证有start和没有的区别!)
assume cs:code,ds:data
data segment
db 'abcde'
db 'ADCDEFGHIJ'
data ends
code segment
mov ax,data //没有start和有的区别?
mov ds,ax
mov bx,0
mov cx,5
s:
mov al,ds:[bx]
and al,11011111B
mov ds:[bx],al
inc bx
loop s
mov cx,10
s1:
mov al,ds:[bx]
or al,00100000B
mov ds:[bx],al
inc bx
loop s1
mov ax,4c00h
int 21
code ends
end
注:1.DS,1444;CS,1455,这就是有start和么有的区别!ds:ip(PSP区)——>db(数据区)——>最后才是,cs:ip(代码段);本来如果没有start的话,就是DS,1444;CS,1454,即ds:ip(PSP区——>直接是,cs:ip(代码段) ,db( 数据区)没有了。
(2.貌似cs:code,在编译之后就开始生效了;那么ds:data为什么没有生效呢,我做实验的时候还要debug加载执行到那一步,ds才变为data的值?这是为什么,难道因为添加了start了,就直接表示了cs从start处开始,是因为这个吗?)
2.
3.为什么有的程序在masm5.0下,直接执行,但之后用debug加载,看不到执行结果,要重新执行一遍才能看到结果.(那还要在masm5.0下,直接执行有什么用呢,相应的start伪指令不也没什么用吗?start,它加了之后,就是为了能在masm5.0下,直接执行的啊?)——一种解释是,在masm5.0下(它执行它的);而debug加载后(你执行你的,这与每次试验的每次所做debug加载都是重新再来一次是一致的.)
2.问题:将数据复制到后面的一段空间?
//7_2.asm
assume cs:code,ds:data
data segment
db 'welcome to masm!' //16Byte
db '…………………… ' //16Byte
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,16
s:
mov al,ds:[si]
mov ds:[si+16],al //这个题,没有什么好说的.
inc si
loop s
mov ax,4c00h
int 21
code ends
end start
注:1.si/di的使用,a.不能和其他寄存器一样(普通寄存器),分成al、ah;b.其他和bx,就没什么不一样.
2.灵活运用ds:[bx+数值]的3种写法(包括si/di),a.[bx+数值];b.[si/di+数值];c.[bx+si/di+数值],或者[bx][si/di](两者也是寄存器嘛~).记住至今没有看到一起使用[si+di],这种情况!
3.定义一个段的段空间,a.最小,16Byte;b.最大,64KB .
3.问题:(依次)将第一个字母变为大写?
//7_3_1.asm(标准或简洁写法)
assume cs:code,ds:data
data segment
db '1. i ' //均为16Byte
db '2. love '
db '3. the cure '
db '4. you '
db '5. love '
db '6. punk floyed '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,16
s:
mov al,ds:[si+3]
and al,11011111B
mov ds:[si+3],al
add si,16
loop s
mov ax,4c00h
int 21
code ends
end start
//7_3.asm(一开始思维僵硬,很偷懒的想法,被我写成了这样)
assume cs:code,ds:data
data segment
db '1. i '
db '2. love '
db '3. the cure '
db '4. you '
db '5. love '
db '6. punk floyed '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,16
s:
mov al,ds:[si+3]
and al,11011111B
mov ds:[si+3],al
/*mov al,ds:[si+3+16*1] //多麻烦,虽然也能实现题目的要求!
and al,11011111B
mov ds:[si+3+16*1],al
mov al,ds:[si+3+16*2]
and al,11011111B
mov ds:[si+3+16*2],al
mov al,ds:[si+3+16*3]
and al,11011111B
mov ds:[si+3+16*3],al
mov al,ds:[si+3+16*4]
and al,11011111B
mov ds:[si+3+16*4],al
mov al,ds:[si+3+16*5]
and al,11011111B
mov ds:[si+3+16*5],al*/
add si,16
loop s
mov ax,4c00h
int 21
code ends
end start
4.题目:将前3个字母变为大写?
//7_7.asm(因为不知道内嵌套,一开始又进入了桎梏.)
assume cs:code,ds:data
data segment
db 'ibm '
db 'mac '
db 'hui '
db 'del '
db 'len '
db 'ace '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,3
s:
mov al,ds:[si]
and al,11011111B
mov ds:[si],al
/*mov al,ds:[si+16] //也能实现,但特麻烦!
and al,11011111B
mov ds:[si+16],al
mov al,ds:[si+16*2]
and al,11011111B
mov ds:[si+16*2],al
mov al,ds:[si+16*3]
and al,11011111B
mov ds:[si16*3],al
mov al,ds:[si+16*4]
and al,11011111B
mov ds:[si+16*4],al
mov al,ds:[si+16*5]
and al,11011111B
mov ds:[si+16*5],al*/
add si,1
loop s
mov ax,4c00h
int 21
code ends
end start
//7_7_1.asm(简洁的写法)
assume cs:code,ds:data
data segment
db 'ibm ' //均为16Byte
db 'mac '
db 'hui '
db 'del '
db 'len '
db 'ace '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov di,0
mov cx,6
s1:
mov dx,cx //1.注意,此处应用寄存器(dx),保存cx,以防止内嵌套将其值覆盖.(寄存器暂存数据,缺点是寄存器个数毕竟有限)
mov bx,0
mov cx,3
s:
mov al,ds:[bx+di]
and al,11011111B
mov ds:[bx+di],al
inc bx
loop s
add di,16
mov cx,dx
loop s1
mov ax,4c00h
int 21
code ends
end start
下面两个源代码就是对暂存数据的优化:
//7_8.asm和7_9.asm
assume cs:code,ds:data
data segment
db '1. ibm '
db '2. mac '
db '3. hui '
db '4. del '
db '5. len '
db '6. ace '
dw 0 //定义一个字的内存
data ends
code segment
start:
mov ax,data
mov ds,ax
mov di,0
mov cx,6
s1:
mov ds:[60h],cx //2.换成了一个内存单元,用内存单元来暂存数据.(缺点是,60h不好找或记住!)
mov bx,3
mov cx,3
s:
mov al,ds:[bx+di]
and al,11011111B
mov ds:[bx+di],al
inc bx
loop s
add di,16
mov cx,ds:[60h]
loop s1
mov ax,4c00h
int 21
code ends
end start
//7_9.asm
assume cs:code,ds:data
data segment
db '1. ibm '
db '2. mac '
db '3. hui '
db '4. del '
db '5. len '
db '6. ace '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,0020h //3.最合理的是,使用栈来暂存数据.
mov ss,ax
mov sp,10h
mov di,0
mov cx,6
s1:
push cx
mov bx,3
mov cx,3
s:
mov al,ds:[bx+di]
and al,11011111B
mov ds:[bx+di],al
inc bx
loop s
add di,16
pop cx
loop s1
mov ax,4c00h
int 21
code ends
end start
//7_1.asm(正确代码)
assume cs:code,ds:data
data segment
db 'abcde'
db 'ADCDEFGHIJ'
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 //(1.为什么不能直接,and ds:[bx],11011111B 呢?这次不是可以确定了要操作对象是一个字节吗?)——书上的例子只有寄存器与数据操作这一种情况,and al,11011111B (and/or用的是寄存器与数据打交道.)
mov ds:[bx],al //(绿色表示没有解决的问题,或存疑的地方?有待以后解决之!)
inc bx
loop s
mov cx,10
s1:
mov al,ds:[bx]
or al,00100000B
mov ds:[bx],al
inc bx
loop s1
mov ax,4c00h
int 21
code ends
end start
//7_1_1.asm(为了验证有start和没有的区别!)
assume cs:code,ds:data
data segment
db 'abcde'
db 'ADCDEFGHIJ'
data ends
code segment
mov ax,data //没有start和有的区别?
mov ds,ax
mov bx,0
mov cx,5
s:
mov al,ds:[bx]
and al,11011111B
mov ds:[bx],al
inc bx
loop s
mov cx,10
s1:
mov al,ds:[bx]
or al,00100000B
mov ds:[bx],al
inc bx
loop s1
mov ax,4c00h
int 21
code ends
end
注:1.DS,1444;CS,1455,这就是有start和么有的区别!ds:ip(PSP区)——>db(数据区)——>最后才是,cs:ip(代码段);本来如果没有start的话,就是DS,1444;CS,1454,即ds:ip(PSP区——>直接是,cs:ip(代码段) ,db( 数据区)没有了。
(2.貌似cs:code,在编译之后就开始生效了;那么ds:data为什么没有生效呢,我做实验的时候还要debug加载执行到那一步,ds才变为data的值?这是为什么,难道因为添加了start了,就直接表示了cs从start处开始,是因为这个吗?)
2.
3.为什么有的程序在masm5.0下,直接执行,但之后用debug加载,看不到执行结果,要重新执行一遍才能看到结果.(那还要在masm5.0下,直接执行有什么用呢,相应的start伪指令不也没什么用吗?start,它加了之后,就是为了能在masm5.0下,直接执行的啊?)——一种解释是,在masm5.0下(它执行它的);而debug加载后(你执行你的,这与每次试验的每次所做debug加载都是重新再来一次是一致的.)
2.问题:将数据复制到后面的一段空间?
//7_2.asm
assume cs:code,ds:data
data segment
db 'welcome to masm!' //16Byte
db '…………………… ' //16Byte
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,16
s:
mov al,ds:[si]
mov ds:[si+16],al //这个题,没有什么好说的.
inc si
loop s
mov ax,4c00h
int 21
code ends
end start
注:1.si/di的使用,a.不能和其他寄存器一样(普通寄存器),分成al、ah;b.其他和bx,就没什么不一样.
2.灵活运用ds:[bx+数值]的3种写法(包括si/di),a.[bx+数值];b.[si/di+数值];c.[bx+si/di+数值],或者[bx][si/di](两者也是寄存器嘛~).记住至今没有看到一起使用[si+di],这种情况!
3.定义一个段的段空间,a.最小,16Byte;b.最大,64KB .
3.问题:(依次)将第一个字母变为大写?
//7_3_1.asm(标准或简洁写法)
assume cs:code,ds:data
data segment
db '1. i ' //均为16Byte
db '2. love '
db '3. the cure '
db '4. you '
db '5. love '
db '6. punk floyed '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,16
s:
mov al,ds:[si+3]
and al,11011111B
mov ds:[si+3],al
add si,16
loop s
mov ax,4c00h
int 21
code ends
end start
//7_3.asm(一开始思维僵硬,很偷懒的想法,被我写成了这样)
assume cs:code,ds:data
data segment
db '1. i '
db '2. love '
db '3. the cure '
db '4. you '
db '5. love '
db '6. punk floyed '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,16
s:
mov al,ds:[si+3]
and al,11011111B
mov ds:[si+3],al
/*mov al,ds:[si+3+16*1] //多麻烦,虽然也能实现题目的要求!
and al,11011111B
mov ds:[si+3+16*1],al
mov al,ds:[si+3+16*2]
and al,11011111B
mov ds:[si+3+16*2],al
mov al,ds:[si+3+16*3]
and al,11011111B
mov ds:[si+3+16*3],al
mov al,ds:[si+3+16*4]
and al,11011111B
mov ds:[si+3+16*4],al
mov al,ds:[si+3+16*5]
and al,11011111B
mov ds:[si+3+16*5],al*/
add si,16
loop s
mov ax,4c00h
int 21
code ends
end start
4.题目:将前3个字母变为大写?
//7_7.asm(因为不知道内嵌套,一开始又进入了桎梏.)
assume cs:code,ds:data
data segment
db 'ibm '
db 'mac '
db 'hui '
db 'del '
db 'len '
db 'ace '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,3
s:
mov al,ds:[si]
and al,11011111B
mov ds:[si],al
/*mov al,ds:[si+16] //也能实现,但特麻烦!
and al,11011111B
mov ds:[si+16],al
mov al,ds:[si+16*2]
and al,11011111B
mov ds:[si+16*2],al
mov al,ds:[si+16*3]
and al,11011111B
mov ds:[si16*3],al
mov al,ds:[si+16*4]
and al,11011111B
mov ds:[si+16*4],al
mov al,ds:[si+16*5]
and al,11011111B
mov ds:[si+16*5],al*/
add si,1
loop s
mov ax,4c00h
int 21
code ends
end start
//7_7_1.asm(简洁的写法)
assume cs:code,ds:data
data segment
db 'ibm ' //均为16Byte
db 'mac '
db 'hui '
db 'del '
db 'len '
db 'ace '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov di,0
mov cx,6
s1:
mov dx,cx //1.注意,此处应用寄存器(dx),保存cx,以防止内嵌套将其值覆盖.(寄存器暂存数据,缺点是寄存器个数毕竟有限)
mov bx,0
mov cx,3
s:
mov al,ds:[bx+di]
and al,11011111B
mov ds:[bx+di],al
inc bx
loop s
add di,16
mov cx,dx
loop s1
mov ax,4c00h
int 21
code ends
end start
下面两个源代码就是对暂存数据的优化:
//7_8.asm和7_9.asm
assume cs:code,ds:data
data segment
db '1. ibm '
db '2. mac '
db '3. hui '
db '4. del '
db '5. len '
db '6. ace '
dw 0 //定义一个字的内存
data ends
code segment
start:
mov ax,data
mov ds,ax
mov di,0
mov cx,6
s1:
mov ds:[60h],cx //2.换成了一个内存单元,用内存单元来暂存数据.(缺点是,60h不好找或记住!)
mov bx,3
mov cx,3
s:
mov al,ds:[bx+di]
and al,11011111B
mov ds:[bx+di],al
inc bx
loop s
add di,16
mov cx,ds:[60h]
loop s1
mov ax,4c00h
int 21
code ends
end start
//7_9.asm
assume cs:code,ds:data
data segment
db '1. ibm '
db '2. mac '
db '3. hui '
db '4. del '
db '5. len '
db '6. ace '
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,0020h //3.最合理的是,使用栈来暂存数据.
mov ss,ax
mov sp,10h
mov di,0
mov cx,6
s1:
push cx
mov bx,3
mov cx,3
s:
mov al,ds:[bx+di]
and al,11011111B
mov ds:[bx+di],al
inc bx
loop s
add di,16
pop cx
loop s1
mov ax,4c00h
int 21
code ends
end start
相关文章推荐
- 不同的寻址方式灵活运用(di,si)
- 汇编语言之不同寻址方式的灵活运用
- [汇编语言]-第七章 不同的寻址方式的灵活应用
- C primer plus 第七章 练习9: 编写一个程序,接受一个整数输入,然后显示所有小于或等于该数的素数。
- 8.6寻址方式的综合运用
- 8.6种灵活的寻址方式与其作用
- 《数论》3.6习题3------求一元线性同余方程所有解(不是方程组)基础练习例子&&求逆元
- [汇编语言]-第七章 SI和DI
- (2011.11.06)汇编语言第02章习题(寻址方式与汇编语言程序的组织)
- 寻址方式
- CronTrigger具体运用方式
- 修改win7电脑中所有文件的默认查看方式
- 汇编语言中,SP,BP ,SI,DI作用?
- 记录——《C Primer Plus (第五版)》第七章编程练习第三题
- .Net下采用GET/POST/SOAP方式动态调用WebService的简易灵活方法(C#)
- Python 第七章部分练习
- 32位cpu的寻址方式
- C++ primer 习题练习:6.24
- C++Primer习题第七章
- 算法竞赛入门经典(第2版)3.4.9上机练习习题