鱼C论坛

 找回密码
 立即注册
查看: 2720|回复: 0

[学习笔记] 第七章 更灵活的定位内存地址的方法

[复制链接]
发表于 2017-9-11 01:20:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
7.1节  and 和 or 指令
        (1)and指令,逻辑与指令,按位进行与运算。
如: mov al, 01100011B
        and al,  00111011B
       
        al的结果为:00100011B

        通过该指令可以将操作对象的相应位设为0,其他位不变。例如:
        将al的第6位设为0的指令是:and al, 10111111B
        将al的第7位设为0的指令是:and al, 01111111B

        (2)or指令,逻辑或指令按位或运算。
如: mov al, 01100011B
        or al, 00111011B

        al的结果为:01111011B

        通过该指令可以将操作对象的相应位设置为1, 其他位不变。例如:
        将al的第6位设为1的指令是:or al, 01000000B
        将al 的第7位设为1的指令是:or al, 10000000B

7.3节  以字符的形式给出的数据

        我们在汇编的程序中,用'......'的方式指明数据是以字符的形式给出的,编译器把他们转化为相对应的ASCII码

7.4节  大小写转换的问题

        先看一副图:
1.png

从中可以看出, 就ASCII码的二进制来看,除第5位(从0开始算)的外,大写字母和小写字母的其他各位都一样,大写字母ASCII码的第五位是0,小写字母的第5位为1。知道这个规律, 我们想转换大小写字母就只需要转换其第5位的二进制是0(大写字母)还是1(小写字母)。

问题:将data段中的第一个字符串转换为大写,第二个字符串转换为小写。代码:
assume cs: code 

data segment 

        db 'BaSic'
        db 'iForMatioN'
        
data ends 

code segment 

start : mov ax, data 
                mov ds, ax 
                mov bx, 0
                
                mov [code][code][code]c
[/code][/code]x, 5
        s : mov al, [bx]
                and al, 11011111B
                mov [bx], al
                inc bx
               
                loop s
               
                mov bx, 0
                mov cx, 11
               
        s0: mov al, [bx]
                or al, 00100000B
                mov [bx], al
                inc bx
               
                loop s0
               
                mov ax, 4c00H
                int 21H
               
code ends
end start
        [/code]

7.5节  [bx + idata]

        mov  ax,[bx + idata]表示在ax中存放两个字节,偏移地址为bx ,加上idata,段地址在ds中

        mov ax, [200 + bx]、mov ax, 200[bx]和mov ax, [bx].200都表示同一个意思,只是不同的形式。

        2.png

7.6节 用[bx + idata]方式进行数组的处理

问题: 将data段中的第一个字符串转换为大写,第二个字符串转换为小写。原本是这样的代码他有两个循环:
assume cs: code 

data segment 

        db 'BaSic'
        db 'iForMatioN'
        
data ends 

code segment 

start : mov ax, data 
                mov ds, ax 
                mov bx, 0
                
                mov cx, 5
        s : mov al, [bx] 
                and al, 11011111B
                mov [bx], al 
                inc bx 
                
                loop s 
                
                mov bx, 0 
                mov cx, 11
                
        s0: mov al, [bx]
                or al, 00100000B
                mov [bx], al 
                inc bx 
                
                loop s0 
                
                mov ax, 4c00H
                int 21H
                
code ends 
end start 
        
       

现在用[bx + idata]可以用一个循环就实现:
assume cs: code 

data segment 

        db 'BaSic'
        db 'MinIX'
        
data ends 

code segment 

start : mov ax, data 
                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
                
code ends 
end start 


SI 和 DI

        si 和 di是和bx功能相近的寄存器,si和di不能分成两个8位寄存器来使用,下面三组指令实现了相同的功能。
(1)mov bx, 0
         mov ax, [bx]

(2)mov si, 0
         mov ax, [si]

(3)mov di, 0
         mov ax, [di]


问题:用bx(si 或 di)的方式是实现将data段中的数据复制到后面:
assume cs: code 

data segment 

        db 'welcome to masm!'
        db '................'
        
data ends 

code segment 

start : mov ax, data 
                mov ds, ax 
                mov bx, 0 
                
                mov cx, 16
        s : mov al, [bx]
                mov [bx + 16], al 
                inc bx 
                
                loop s 
                
                mov ax, 4c00h
                int 21H
                
code ends 
end start 


7.8节[bx + si] 和 [bx + di]

        mov ax, [bx + si]表示将偏移地址为[bx + si](bx中的值加上si中的值),段地址在ds 中的数据放入ax中。
        mov ax, [bx + di]也是差不多



7.9节 [bx + si + idata]和[bx + di +idata]

        mov ax, [bx + si + idata]  将偏移地址为bx中的数值加上si中的数值再加上idata的和,段地址在ds中的数据放入ax中。
        mov ax, [bx + di + idata]也是差不多

        3.png


7.10节 不同的寻址方式的灵活运用

编程:将data段中的每个单词的头一个字母改为大写;
assume cs: code 

data segment 

        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 si, 0
                
                mov cx, 6
        s : mov al, 3[si]
                and al, 11011111B
                mov 3[si], al
                
                add si, 16
                
                loop s 
                
                mov ax, 4c00H
                int 21H
                
code ends 
end start 


编程:将data段中的每个单词改为大写字母:
(1)我自己写的好蠢的代码:
assume cs: code 

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, 3
        s1: mov al, [bx]
                and  al, 11011111B
                mov [bx], al
                inc bx
                
                loop s1
                
                mov bx, 0
                mov cx, 3
        s2: mov al, 16[bx]
                and al, 11011111B
                mov 16[bx], al
                inc bx
                
                loop s2
                
                mov bx, 0
                mov cx, 3
        s3: mov al, 32[bx]
                and al, 11011111B
                mov 32[bx], al 
                inc bx 
                
                loop s3
                
                mov bx, 0
                mov cx, 3
        s4: mov al, 48[bx]
                and al, 11011111B
                mov 48[bx], al
                inc bx
                
                loop s4
                
                mov ax, 4c00H
                int 21H
                
code ends 
end start 

(2)这个是标准版的代码:
assume cs: code 

data segment 

        db 'ibm.............'
        db 'dec.............'
        db 'dos.............'
        db 'vax.............'
        
data ends 

stack segment 

        dw 0, 0, 0, 0, 0, 0, 0, 0
        
stack ends 

code segment 

start :        mov ax, data  
                mov ds, ax

                mov ax, stack 
                mov ss, ax 
                mov sp, 16
                
                mov si, 0
                mov cx, 4
        s : push cx
                mov bx, 0
                 
                mov cx, 3
        s1: mov al, [bx + si]
                and al, 11011111B
                mov [bx + si], al 
                inc bx 
                
                loop s1
                
                pop cx 
                
                add si, 16
                
                loop s 
                
                mov ax, 4c00H
                int 21H
                
code ends 
end start 

这个程序让我们知道了,如果在内层循环中如果寄存器被重复使用的话,就应该用栈将它给保存下来
一般来说,在暂时需要存放数据的时候,我们都应该找栈。

编程:将data段中的每个单词的前四个单词改为大写字母:
assume cs: code 

data segment 

        db '1. display      '
        db '1. brows        '
        db '1. replace      '
        db '1. modify       '
        
data ends 

stack segment 

        dw 0, 0, 0, 0, 0, 0, 0, 0

stack ends 

code segment 

start : mov ax, data 
                mov ds, ax 
                
                mov ax, stack 
                mov ss, ax 
                mov sp, 16
                
                mov si, 0
                mov cx, 4
        s : push cx 
                mov bx, 0
                
                mov cx, 4
        s1: mov al, 3[bx + si]
                and al, 11011111B
                mov 3[bx + si], al 
                inc bx 
                
                loop s1 
                
                pop cx 
                
                add si, 16
                
                loop s 
                
                mov ax, 4c00H
                int 21h
                
code ends 
end start 


第七张总结
(1)这章我们学会了更多灵活的定位内存,如:新增8位寄存器si和di,用[bx + idata]、[bx + si ]、[bx + si + idata]等方式定位内存
(2)二重循环应该用栈将要重复使用的寄存器push起来相应的要pop出去,这两者要一一对应
(3)大小写转换的问题,将数据的二进制的第五位(从0开始算)该为0或1
(4)and和or指令,本章主要将它应用到转换大小写

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-6 10:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表