若余相思 发表于 2017-9-11 01:20:01

第七章 更灵活的定位内存地址的方法

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节大小写转换的问题

        先看一副图:


从中可以看出, 就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 cx, 5
        s : mov al,
                and al, 11011111B
                mov , al
                inc bx
               
                loop s
               
                mov bx, 0
                mov cx, 11
               
        s0: mov al,
                or al, 00100000B
                mov , al
                inc bx
               
                loop s0
               
                mov ax, 4c00H
                int 21H
               
code ends
end start
       

7.5节

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

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

       

7.6节 用方式进行数组的处理

问题: 将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,
                and al, 11011111B
                mov , al
                inc bx
               
                loop s
               
                mov bx, 0
                mov cx, 11
               
        s0: mov al,
                or al, 00100000B
                mov , al
                inc bx
               
                loop s0
               
                mov ax, 4c00H
                int 21H
               
code ends
end start
       
       

现在用可以用一个循环就实现:
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,
                and al, 11011111B
                mov , al
               
                mov al, 5
                or al, 00100000B
                mov 5, 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,

(2)mov si, 0
       mov ax,

(3)mov di, 0
       mov ax,


问题:用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,
                mov , al
                inc bx
               
                loop s
               
                mov ax, 4c00h
                int 21H
               
code ends
end start


7.8节 和

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



7.9节 和

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

       


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
                and al, 11011111B
                mov 3, 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,
                andal, 11011111B
                mov , al
                inc bx
               
                loop s1
               
                mov bx, 0
                mov cx, 3
        s2: mov al, 16
                and al, 11011111B
                mov 16, al
                inc bx
               
                loop s2
               
                mov bx, 0
                mov cx, 3
        s3: mov al, 32
                and al, 11011111B
                mov 32, al
                inc bx
               
                loop s3
               
                mov bx, 0
                mov cx, 3
        s4: mov al, 48
                and al, 11011111B
                mov 48, 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,
                and al, 11011111B
                mov , 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
                and al, 11011111B
                mov 3, 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,用、、等方式定位内存
(2)二重循环应该用栈将要重复使用的寄存器push起来相应的要pop出去,这两者要一一对应
(3)大小写转换的问题,将数据的二进制的第五位(从0开始算)该为0或1
(4)and和or指令,本章主要将它应用到转换大小写
页: [1]
查看完整版本: 第七章 更灵活的定位内存地址的方法