鱼C论坛

 找回密码
 立即注册
查看: 2597|回复: 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段中的第一个字符串转换为大写,第二个字符串转换为小写。代码:
  1. assume cs: code

  2. data segment

  3.         db 'BaSic'
  4.         db 'iForMatioN'
  5.        
  6. data ends

  7. code segment

  8. start : mov ax, data
  9.                 mov ds, ax
  10.                 mov bx, 0
  11.                
  12.                 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段中的第一个字符串转换为大写,第二个字符串转换为小写。原本是这样的代码他有两个循环:

  1. assume cs: code

  2. data segment

  3.         db 'BaSic'
  4.         db 'iForMatioN'
  5.        
  6. data ends

  7. code segment

  8. start : mov ax, data
  9.                 mov ds, ax
  10.                 mov bx, 0
  11.                
  12.                 mov cx, 5
  13.         s : mov al, [bx]
  14.                 and al, 11011111B
  15.                 mov [bx], al
  16.                 inc bx
  17.                
  18.                 loop s
  19.                
  20.                 mov bx, 0
  21.                 mov cx, 11
  22.                
  23.         s0: mov al, [bx]
  24.                 or al, 00100000B
  25.                 mov [bx], al
  26.                 inc bx
  27.                
  28.                 loop s0
  29.                
  30.                 mov ax, 4c00H
  31.                 int 21H
  32.                
  33. code ends
  34. end start
  35.        
复制代码

       

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

  2. data segment

  3.         db 'BaSic'
  4.         db 'MinIX'
  5.        
  6. data ends

  7. code segment

  8. start : mov ax, data
  9.                 mov ds, ax
  10.                 mov bx, 0
  11.                
  12.                 mov cx, 5
  13.         s : mov al, [bx]
  14.                 and al, 11011111B
  15.                 mov [bx], al
  16.                
  17.                 mov al, 5[bx]
  18.                 or al, 00100000B
  19.                 mov 5[bx], al
  20.                 inc bx
  21.                
  22.                 loop s
  23.                
  24.                 mov ax, 4c00H
  25.                 int 21H
  26.                
  27. code ends
  28. 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段中的数据复制到后面:
  1. assume cs: code

  2. data segment

  3.         db 'welcome to masm!'
  4.         db '................'
  5.        
  6. data ends

  7. code segment

  8. start : mov ax, data
  9.                 mov ds, ax
  10.                 mov bx, 0
  11.                
  12.                 mov cx, 16
  13.         s : mov al, [bx]
  14.                 mov [bx + 16], al
  15.                 inc bx
  16.                
  17.                 loop s
  18.                
  19.                 mov ax, 4c00h
  20.                 int 21H
  21.                
  22. code ends
  23. 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段中的每个单词的头一个字母改为大写;
  1. assume cs: code

  2. data segment

  3.         db '1. file         '
  4.         db '2. edit         '
  5.         db '3. search       '
  6.         db '4. view         '
  7.         db '5. options      '
  8.         db '6. help         '
  9.        
  10. data ends

  11. code segment

  12. start : mov ax, data
  13.                 mov ds, ax
  14.                 mov si, 0
  15.                
  16.                 mov cx, 6
  17.         s : mov al, 3[si]
  18.                 and al, 11011111B
  19.                 mov 3[si], al
  20.                
  21.                 add si, 16
  22.                
  23.                 loop s
  24.                
  25.                 mov ax, 4c00H
  26.                 int 21H
  27.                
  28. code ends
  29. end start
复制代码



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

  2. data segment

  3.         db 'ibm.............'
  4.         db 'dec.............'
  5.         db 'dos.............'
  6.         db 'vax.............'
  7.        
  8. data ends

  9. code segment

  10. start : mov ax, data  
  11.                 mov ds, ax
  12.                 mov bx, 0
  13.                
  14.                 mov cx, 3
  15.         s1: mov al, [bx]
  16.                 and  al, 11011111B
  17.                 mov [bx], al
  18.                 inc bx
  19.                
  20.                 loop s1
  21.                
  22.                 mov bx, 0
  23.                 mov cx, 3
  24.         s2: mov al, 16[bx]
  25.                 and al, 11011111B
  26.                 mov 16[bx], al
  27.                 inc bx
  28.                
  29.                 loop s2
  30.                
  31.                 mov bx, 0
  32.                 mov cx, 3
  33.         s3: mov al, 32[bx]
  34.                 and al, 11011111B
  35.                 mov 32[bx], al
  36.                 inc bx
  37.                
  38.                 loop s3
  39.                
  40.                 mov bx, 0
  41.                 mov cx, 3
  42.         s4: mov al, 48[bx]
  43.                 and al, 11011111B
  44.                 mov 48[bx], al
  45.                 inc bx
  46.                
  47.                 loop s4
  48.                
  49.                 mov ax, 4c00H
  50.                 int 21H
  51.                
  52. code ends
  53. end start
复制代码


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

  2. data segment

  3.         db 'ibm.............'
  4.         db 'dec.............'
  5.         db 'dos.............'
  6.         db 'vax.............'
  7.        
  8. data ends

  9. stack segment

  10.         dw 0, 0, 0, 0, 0, 0, 0, 0
  11.        
  12. stack ends

  13. code segment

  14. start :        mov ax, data  
  15.                 mov ds, ax

  16.                 mov ax, stack
  17.                 mov ss, ax
  18.                 mov sp, 16
  19.                
  20.                 mov si, 0
  21.                 mov cx, 4
  22.         s : push cx
  23.                 mov bx, 0
  24.                  
  25.                 mov cx, 3
  26.         s1: mov al, [bx + si]
  27.                 and al, 11011111B
  28.                 mov [bx + si], al
  29.                 inc bx
  30.                
  31.                 loop s1
  32.                
  33.                 pop cx
  34.                
  35.                 add si, 16
  36.                
  37.                 loop s
  38.                
  39.                 mov ax, 4c00H
  40.                 int 21H
  41.                
  42. code ends
  43. end start
复制代码


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

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

  2. data segment

  3.         db '1. display      '
  4.         db '1. brows        '
  5.         db '1. replace      '
  6.         db '1. modify       '
  7.        
  8. data ends

  9. stack segment

  10.         dw 0, 0, 0, 0, 0, 0, 0, 0

  11. stack ends

  12. code segment

  13. start : mov ax, data
  14.                 mov ds, ax
  15.                
  16.                 mov ax, stack
  17.                 mov ss, ax
  18.                 mov sp, 16
  19.                
  20.                 mov si, 0
  21.                 mov cx, 4
  22.         s : push cx
  23.                 mov bx, 0
  24.                
  25.                 mov cx, 4
  26.         s1: mov al, 3[bx + si]
  27.                 and al, 11011111B
  28.                 mov 3[bx + si], al
  29.                 inc bx
  30.                
  31.                 loop s1
  32.                
  33.                 pop cx
  34.                
  35.                 add si, 16
  36.                
  37.                 loop s
  38.                
  39.                 mov ax, 4c00H
  40.                 int 21h
  41.                
  42. code ends
  43. 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-4-30 18:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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