zoukankan      html  css  js  c++  java
  • 汇编语言学习——第七章 更灵活定位内存地址

    在这一章中,我们学习一些更灵活的定位内存地址的方法和相关的编程方法。

    1、 两条指令and和or。

    在汇编程序中,and 主要是置0, or主要是置1 。

    例如:

    将al的第6位设为0:and al, 10111111B

    将al的第6位设为1:or al, 01000000B

     

    2、 以字符的形式给出数据

    在汇编程序中,用 “x”的方式指明数据是以字符的形式给出的,编译器将把它们转化为相对应的ASCII码。

    如: MOV AX, 'A'   表示将‘A'的ASCII码 65赋值给AX。

    3、大小写转换的问题

    要改变一个字母的大小写,实际上就是要改变它所对应的ASCII 码。

    小写字母的ASCII码值比大写字母的ASCII码值大20H (32)

    大写     二进制             小写       二进制
     A         01000001          a         01100001
     B         01000010          b         01100010
     C         01000011          c         01100011
     D         01000100          d         01100100

    可以看出,就ASCII码的二进制形式来看,除第5位(位数从0开始计算)外,

    大写字母和小写字母的其他各位都一样。

    大写字母ASCII码的第5位(位数从0开始计算)为0,小写字母的第5位为1。

    也就是说一个字母,我们不管它原来是大写还是小写:

    我们将它的第5位置0,它就必将变为大写字母;将它的第5 位置1,它就必将变为小写字母。

    一道大小写转换的程序:

    ;大小写转换问题, BaSiC ,进行转换
    ASSUME CS:CODESG, DS:DATASG
    
    DATASG SEGMENT
    DB 'BaSiC'
    DATASG ENDS
    
    CODESG SEGMENT
    START:
     MOV AX, DATASG
     MOV DS, AX
    
     MOV BX, 0 
     MOV CX, 5
    S:
     MOV AL, [BX]
     OR AL, 00100000B   ; 转换为小写
     MOV [BX],AL
     INC BX
     LOOP S
    
     MOV AX, 4C00H
     INT 21H
    CODESG ENDS
    END START
    

    4、新的表示 [bx+idata]

    指令mov ax,[bx+200]也可以写成如下格式(常用):

    mov ax,[200+bx]

    mov ax,200[bx]

    [bx+idata]的方式为高级语言实现数组提供了便利机制。

    一道例题:

    ; 用[bx+idata]的方式进行数组的处理
    ; 将datasg 定义的第一个字符串转换为大写,第二个字符串转换为小写
    
    ASSUME CS:CODESG, 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, 0[BX]
     AND AL, 0DFH   ; 相当于 11011111B
     MOV 0[BX], AL
     
     MOV AL, 5[BX]
     OR AL, 20H
     MOV 5[BX], AL
     
     INC BX
     LOOP S
    
    
     MOV AX, 4C00H
     INT 21H
    CODESG ENDS
    END START
    


    5、SI 和 DI

    SI和DI是8086CPU中和bx功能相近的寄存器,但是SI和DI不能够分成两个8 位寄存器来使用

    例题:

    ;用寄存器SI和DI实现将字符串‘welcome to masm!’复制到它后面的数据区中。
    
    ASSUME CS:CODESG, DS:DATASG
    
    DATASG SEGMENT
     DB 'welcome to masm!'
    DATASG ENDS
    
    CODESG SEGMENT
    START:
     MOV AX, DATASG
     MOV DS, AX
     
     MOV SI,0
     MOV DI,16
     MOV CX, 16
    
    S:
     MOV AL,[SI]
     MOV [DI], AL
     INC DI
     INC SI
     LOOP S
    
    
     MOV AX, 4C00H
     INT 21H
    CODESG ENDS
    END START
    
    

    我很不明白: 为什么最后一个'!'复制不了??????

    6、 不同的寻址方式的灵活应用

    如果我们比较一下前面用到的几种定位内存地址的方法(可称为寻址方式),就可以发现有以下几种方式:

    (1)[iata] 用一个常量来表示地址,可用于直接定位一个内存单元;

    (2)[bx]用一个变量来表示内存地址,可用于间接定位一个内存单元;

    (3)[bx+idata] 用一个变量和常量表示地址,可在一个起始地址的基础上用变量间接定位一个内存单元;

    (4)[bx+si]用两个变量表示地址;

    (5)[bx+si+idata] 用两个变量和一个常量表示地址。

     

    7、书本几道例题

    1); 将datasg段中的每个单词的头一个字符改为大写字母

    ASSUME CS:CODESG, DS:DATASG
    
    DATASG SEGMENT
     DB '1. file         '
     DB '2. edit         '
     DB '3. search       '
     DB '4. view         '
     DB '5. option       '
     DB '6. help         '
    DATASG ENDS
    
    CODESG SEGMENT
    START:
     MOV AX, DATASG
     MOV DS, AX
     
     MOV SI, 3
     MOV CX, 6
    
    S:
     MOV AL, [SI]
     AND AL, 0DFH
     MOV [SI],AL
     ADD SI, 16
     LOOP S
     
     MOV AX, 4C00H
     INT 21H
    
    CODESG ENDS
    END START
    

    2); 将 datasg段中的每个单词改为大写字母

    ASSUME CS:CODESG, DS:DATASG
    
    DATASG SEGMENT
     db 'ibm             '
     db 'dec             '
     db 'dos             '
     db 'vax             '
    DATASG ENDS
    
    CODESG SEGMENT
    START:
     MOV AX, DATASG
     MOV DS, AX
     
     MOV BX, 0
     MOV CX, 4
    S:
     MOV SI, 0
     MOV DX, CX  ; 临时存放cx的数值
     MOV CX, 3
    S1:
     MOV AL, [BX+SI]
     AND AL, 0DFH
     MOV [BX+SI],AL
     INC SI
     LOOP S1
     
     ADD BX, 16
     MOV CX, DX
     LOOP S
    
     MOV AX, 4C00H
     INT 21H
    CODESG ENDS
    END START
    

    分析: 因为这里涉及到两重循环,而只有一个CX保存循环次数,那么意味着在进入内层循环的时候,

    要先把CX暂时存放起来,内层循环执行完毕之后,再将它进行还原。本程序保存在DX中。

    3)利用栈段存储暂时数据

    ; 将 datasg段中的每个单词改为大写字母,利用栈段
    
    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
    STACKSG ENDS
    
    CODESG SEGMENT
    START:
     MOV AX, DATASG
     MOV DS, AX
     MOV AX, STACKSG
     MOV SS, AX
     MOV SP, 16 ; 栈空
     
     MOV BX, 0
     MOV CX, 4
    S:
     MOV SI, 0
     PUSH CX  ;将CX进栈
     MOV CX, 3
    S1:
     MOV AL, [BX+SI]
     AND AL, 0DFH
     MOV [BX+SI],AL
     INC SI
     LOOP S1
     
     ADD BX, 16
     POP CX   ; 将CX 出栈
     LOOP S
    
     MOV AX, 4C00H
     INT 21H
    CODESG ENDS
    END START
    

    分析: 这里使用了栈来存储数据,这是一个比较好的做法,使用栈的时候,应该注意栈顶定位和栈顶越界问题。

    4); 将datasg段中的每个单词的前四个字母改为大写字母

    ASSUME CS:CODESG, DS:DATASG, SS:STACKSG
    
    DATASG SEGMENT
     DB '1. display      '
     DB '2. brows        '
     DB '3. replace      '
     DB '4. modify       '
    DATASG ENDS
    
    STACKSG SEGMENT
     dw 0,0,0,0,0,0,0,0
    STACKSG ENDS
    
    CODESG SEGMENT
    START:
     MOV AX, DATASG
     MOV DS, AX
     MOV AX, STACKSG
     MOV SS, AX
     MOV SP, 16 ; 栈为空
     
     MOV BX, 0
     MOV CX, 4
    S:
     MOV SI, 3
     PUSH CX
     MOV CX, 4
    S1:
     MOV AL, [BX+SI]
     AND AL, 0DFH
     MOV [BX+SI], AL
     INC SI
     LOOP S1
     
     ADD BX, 16
     POP CX
     LOOP S
     
     MOV AX, 4C00H
     INT 21H
    CODESG ENDS
    END START
    

    以上的程序可以看出:

    暂存的数据,我们可以存放在寄存器中,也可以存放在内存中。

    因为寄存器的数量有限,所以我们可以将暂存的数据放到内存单元中,

    需要使用的时候,再从内存单元中恢复。这样的话,我们就需要开辟一段内存空间。

    在需要暂存数据的时候,我们都应该使用栈,这样才是一个比较好的做法。

    个人总结: 本章的重点主要有:

    1)理解and和or指令如何使某一位置1或是0

    2)理解大小写的转换问题(改变大小写,其实就是改变它所对应的ASCII 码)

    3)弄明白书本的几道例题(必须掌握的知识)

    4) 理解栈的作用(重点)

  • 相关阅读:
    第04组(64) 团队展示
    结对编程作业
    第一次个人编程作业
    寒假第二份大礼包
    热身礼包初体验,欢欢喜喜过大年
    第08组 Beta冲刺 (1/5)
    第08组 Alpha冲刺 总结
    第五次作业
    第08组 Alpha冲刺 (6/6)
    第08组 Alpha冲刺 (5/6)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3268809.html
Copyright © 2011-2022 走看看